85 lines
2.3 KiB
Rust
85 lines
2.3 KiB
Rust
//! 项目管理器 — 项目的 CRUD 与生命周期管理
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
use df_types::types::{IdeaId, Priority, ProjectId, ProjectStatus};
|
||
|
||
/// 项目实体
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Project {
|
||
/// 唯一 ID
|
||
pub id: ProjectId,
|
||
/// 项目名称
|
||
pub name: String,
|
||
/// 项目描述
|
||
pub description: String,
|
||
/// 当前状态
|
||
pub status: ProjectStatus,
|
||
/// 来源想法 ID(可选,如果是从想法晋升来的)
|
||
pub idea_id: Option<IdeaId>,
|
||
/// 优先级
|
||
pub priority: Priority,
|
||
/// 标签
|
||
pub tags: Vec<String>,
|
||
/// 创建时间
|
||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||
/// 更新时间
|
||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||
}
|
||
|
||
/// 创建项目的输入
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct CreateProjectInput {
|
||
pub name: String,
|
||
pub description: String,
|
||
pub idea_id: Option<IdeaId>,
|
||
#[serde(default)]
|
||
pub priority: Priority,
|
||
#[serde(default)]
|
||
pub tags: Vec<String>,
|
||
}
|
||
|
||
/// 项目管理器
|
||
pub struct ProjectManager;
|
||
|
||
impl ProjectManager {
|
||
/// 创建新项目
|
||
///
|
||
/// TODO: 接入存储层持久化
|
||
pub fn create(input: CreateProjectInput) -> Project {
|
||
let now = chrono::Utc::now();
|
||
Project {
|
||
id: df_types::types::new_id(),
|
||
name: input.name,
|
||
description: input.description,
|
||
status: ProjectStatus::Planning,
|
||
idea_id: input.idea_id,
|
||
priority: input.priority,
|
||
tags: input.tags,
|
||
created_at: now,
|
||
updated_at: now,
|
||
}
|
||
}
|
||
|
||
/// 从想法创建项目
|
||
pub fn create_from_idea(name: String, description: String, idea_id: IdeaId) -> Project {
|
||
Self::create(CreateProjectInput {
|
||
name,
|
||
description,
|
||
idea_id: Some(idea_id),
|
||
priority: Priority::default(),
|
||
tags: Vec::new(),
|
||
})
|
||
}
|
||
|
||
/// 更新项目状态
|
||
///
|
||
/// TODO: 状态转换校验
|
||
pub fn transition_status(project: &mut Project, new_status: ProjectStatus) -> anyhow::Result<()> {
|
||
// TODO: 校验状态转换是否合法
|
||
project.status = new_status;
|
||
project.updated_at = chrono::Utc::now();
|
||
Ok(())
|
||
}
|
||
}
|