【项目中心】项目详情与迭代
项目详情与迭代属于项目中心,由 yudao-module-pms 后端模块的 pm.project、pm.iteration 包实现,前端实现在 @/views/pms/pm/project/detail 和 @/views/pms/pm/iteration 目录。
项目详情是项目执行的统一入口。通用项目围绕「项目概况 → 任务 → 甘特图」展开,敏捷开发项目增加「待规划 → 迭代 → 全部事项 → 需求 / 任务 / 缺陷 → 工时」页签。
- 项目概况:展示公告、项目基本信息、完成趋势、未完成迭代和分配给当前用户的工作项。
- 待规划:敏捷项目可以把 Backlog 工作项拖入迭代,也可以在迭代内直接创建工作项。
- 迭代:维护迭代周期、目标、负责人和状态,进入迭代详情查看事项分布、趋势和燃尽数据。
- 甘特图与工时:从工作项的开始 / 截止时间绘制时间轴,从工时记录聚合项目日报。
本文涉及表如下图所示:
# 1. 取数来源
项目详情、概况、待规划看板和甘特图没有独立的展示表,涉及的数据表如下:
| 表 | 关系与用途 |
|---|---|
pms_project | 保存项目名称、类型、可见范围、周期、状态和最近访问时间 |
pms_project_announcement | 保存项目公告,项目概况只展示最新一条 |
pms_project_member | 保存项目成员级别,决定详情页是否可编辑,以及负责人下拉的可选范围 |
pms_iteration | 保存迭代周期、目标、负责人和状态,是待规划和甘特图的分组依据 |
pms_work_item | 保存工作项的状态、负责人、迭代、父子关系和起止时间,是概况、待规划和甘特图的数据源 |
pms_work_item_work_log | 保存工时记录,是项目工时报表的数据源 |
本篇只展开 pms_iteration,详见 §3.1 表结构。
# 2. 项目详情
项目详情,由 PmsProjectController 提供接口(/pms/pm/project),页签数据由工作项和迭代接口提供。
# 2.1 管理后台
对应 [PMS 项目管理 -> 项目中心 -> 我的项目] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/pms/pm/project/detail 目录,主要子组件为 ProjectOverview.vue、PlanningBoard.vue、ProjectGantt.vue 和 ProjectWorkLog.vue。
# 项目概况
点击「我的项目」中的项目名称进入详情,进入时会更新项目的最近访问时间,用于项目列表按最近访问排序。
页面展示项目名称、项目类型、可见范围、周期、描述、项目进度、成员数量和最新公告。通用项目展示近 14 日完成趋势,敏捷项目展示未完成迭代卡片和状态。「分配给我的」区域展示当前用户未完成的工作项,点击标题打开 WorkItemDetail.vue。

# 待规划
敏捷项目进入「待规划」页签后,PlanningBoard.vue 左侧展示未规划的 Backlog 工作项,右侧按未完成迭代分组展示已规划的工作项。
拖拽工作项进入迭代时,先调用 updateWorkItemIteration 修改所属迭代,再调用 updateWorkItemPlanningSort 保存目标区域顺序;拖回 Backlog 时把 iterationId 置空。有筛选条件时页面会禁用拖拽,避免把局部结果覆盖完整排序。
Backlog 和迭代内均支持快速创建工作项,迭代标题旁可以快速创建迭代。

# 事项页签
「全部事项」使用 WorkItemAllList.vue,需求、任务和缺陷分别使用 WorkItemList.vue。通用项目只显示任务;敏捷项目按工作项类型切换需求、任务和缺陷。点击事项标题打开工作项详情抽屉,详见 《【项目中心】工作项与协作》。

# 甘特图
ProjectGantt.vue 并行加载项目全部工作项和敏捷项目迭代,只展示同时填写开始时间和截止时间的工作项。页面支持标题关键词、日期范围和日 / 周 / 月 / 年视图;敏捷项目按迭代和待规划分组,并支持父子工作项折叠。
甘特图数据仍来自工作项和迭代的分页接口,没有独立的甘特图表。

# 工时
敏捷项目的「工时」页签使用 ProjectWorkLog.vue,由 getWorkLogProjectReport 按迭代、工作项和日期聚合实际投入时长。默认日期范围为本月第一天至今天,支持按迭代名称和日期范围筛选,点击工作项可打开详情。
没有迭代的工作项归入「未规划事项」分组。工时表结构和登记规则详见 《【项目中心】工作项与协作》。

# 3. 迭代
迭代,由 PmsIterationController 提供接口(/pms/pm/iteration)。迭代只属于一个项目,工作项通过 iteration_id 关联迭代。
# 3.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `pms_iteration` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`project_id` bigint NOT NULL COMMENT '项目编号',
`owner_user_id` bigint DEFAULT NULL COMMENT '负责人用户编号',
`name` varchar(100) NOT NULL COMMENT '迭代名称',
`target` varchar(255) DEFAULT NULL COMMENT '迭代目标',
`description` text DEFAULT NULL COMMENT '迭代描述',
`start_time` datetime DEFAULT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`finish_time` datetime DEFAULT NULL COMMENT '完成时间',
`sort` int NOT NULL DEFAULT 0 COMMENT '显示顺序',
`status` int NOT NULL DEFAULT 1 COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='PMS 迭代';
① project_id 关联 pms_project 表的 id 字段,owner_user_id 关联 system_users 表的 id 字段。负责人的可选范围由当前项目成员决定,PMS 不复制后台账号表,也不把负责人写成独立的员工或部门记录。
② start_time、end_time 可以同时为空;填写周期时必须同时填写,且开始时间早于结束时间。开始迭代时会再次要求两者均有值;完成迭代时写入 finish_time。
③ sort 是项目内的迭代顺序,创建时按项目现有最大顺序递增。列表排序会补充 id 作为稳定的次级排序。
④ 枚举 status 迭代状态(PmsIterationStatusEnum)。详见 §3.2 状态流转。
# 3.2 状态流转
迭代生命周期由 PmsIterationServiceImpl 控制。状态字段为 status:
| 状态值 | 枚举 | 说明 | 可执行操作 |
|---|---|---|---|
1 | PLANNED | 未开始 | 编辑、开始迭代、删除 |
2 | ACTIVE | 进行中 | 编辑、完成迭代、删除 |
3 | COMPLETED | 已完成 | 编辑、删除 |
状态流转说明
新建迭代 ──→ 未开始(1) ──开始──→ 进行中(2) ──完成──→ 已完成(3)
│ │ │
└──────────────┴────── 删除 ───────┘
- 创建(
createIteration):Service 强制设置为未开始,创建请求不能自行传入状态,同时校验项目处于进行中。 - 开始(
startIteration):只允许未开始迭代,补充开始和截止时间后变为进行中。开始后,待规划看板才会把该迭代作为可拖入目标。 - 完成(
completeIteration):只允许进行中迭代,写入完成时间。完成后工作项仍保留在该迭代中,项目处于进行中且用户有写权限时,仍可按项目写权限继续新增和编辑。 - 删除(
deleteIteration):项目处于进行中且当前用户有项目写权限时,任意状态的迭代都可以删除。删除前会把关联工作项的iteration_id置空,不删除工作项。 - 项目锁定:项目归档或移入回收站后,所有迭代操作均不可用。
# 3.3 管理后台
对应 [PMS 项目管理 -> 项目中心 -> 我的项目 -> 项目详情 -> 迭代] 页签,对应 yudao-ui-admin-vue3 项目的 @/views/pms/pm/iteration 目录。
# 列表
IterationList.vue 支持按迭代名称和状态筛选,展示编号、名称、状态、进度、负责人和起止日期。点击名称进入隐藏路由 /pms/pm/iteration/detail/:id。

# 新增
点击【新建迭代】打开 IterationForm.vue,填写迭代名称、负责人、开始时间、截止时间、目标和描述。项目编号由详情页传入,状态由后端初始化,负责人只能从项目成员中选择。

# 修改
任意状态的迭代都可以点击【编辑】打开同一个 IterationForm.vue。保存时后端不修改项目编号和迭代状态。
# 开始与完成
未开始迭代点击【开始迭代】打开 IterationStartForm.vue,填写周期后调用 startIteration。进行中迭代点击【完成迭代】并二次确认后调用 completeIteration。

# 删除
点击【删除】并二次确认后,Service 先把该迭代下工作项的 iteration_id 置空,再删除迭代记录。这些工作项会回到待规划区域,不会被一起删除。
# 详情
点击迭代名称进入 /pms/pm/iteration/detail/:id,展示事项总数、状态分布、事项类型分布、近 14 日趋势、燃尽数据和最近动态;敏捷项目详情还提供全部、需求、任务、缺陷页签。
