SpringBoot3+Vue3 项目立项到甘特:审批冻结台账、任务树怎么汇进度
🌐 文档地址:https://ruoyioffice.com
📦 源码1·GitHub:https://github.com/yuqing2026/ruoyi-office
📦 源码2·GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office
📦 源码3·Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 微信:17156169080(备注「RuoYi Office」)
立项还在改预算,任务已经开工;甘特是项目经理手动画的,和 WBS 对不上。RuoYi Office 把申请单和台账拆开:审批通过才冻结立项、按同一 id 物化台账。进度从叶子填报往上卷,甘特读这棵树,不另存一套条形图。
▲ 提交立项 → 审批冻结 → 台账同 id 物化 → 进度上卷。甘特只读任务树,不要手填父进度
引言:项目难在「申请单和执行簿是两本账」
缺的不是甘特组件,是谁在什么时候变成执行对象。
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
本文只讲立项 → 台账 → 任务树 → 甘特。资料库 ACL、OnlyOffice 协同是另一条线,不在这里展开。
菜单:项目管理 → 项目立项 / 项目台账。流程 key:project_create。
一、产品能力:申请单冻结,台账才开工
PMO 批的是立项申请。项目经理干活看的是台账。两张皮必须在「审批通过」这一下接上。
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
申请页 /project/project-apply-info?id= 就能带计划与 WBS、甘特、预算、里程碑——那是草案。通过之前,这些草稿不能冒充现场进度。
二、业务怎么走:冻结、物化、上卷
开发库 PJ202606070002(立项 / 台账 id=18)名称「软件研发项目2026060602」,申请单已立项。台账下 18 条任务,进度由上卷得到约 4.68%;演示数据里台账状态后来被结成已完成,甘特和 WBS 仍是同一棵树。
1. 立项:提交才进审批
保存是草稿。submitProjectInfo 把状态改成审批中(1),流程变量带编号和「项目名称 + 立项申请」,key 是 project_create。驳回 / 撤回退回草稿,现场不能当已批项目用。
▲ /project/project-apply-info?id=18。通过后状态已立项。再改预算应走变更,不是重开申请单
2. 通过:申请单冻结,台账按同一 id 落地
onProcessApproved 做两件事:申请单改已立项(2);upsertFromDraft 把申请单拷成台账。台账主键等于申请单 id,draftProjectId 指回申请单。第一次插入记一条动态「立项审批通过,项目进入台账」;再次回调则更新。
挂了合同、预算为空时,用合同总额当预算基线,避免台账一打开预算是 0。可选地建文档空间、把申请附件编进资料库——那是旁路,主线是台账行必须在。
打开 /project/project-ledger-detail?id=18,默认「任务管理」。这是执行簿:预算 86 万、相对方演示客户,和申请单同一 id,不是另建一行。
▲ /project/project-ledger-detail?id=18 任务管理。叶子填报,父任务进度由子任务加权汇总
3. 进度:叶子填报,父任务上卷
ProjectTaskRollupService 先给没有孩子的叶子按执行记录算进度和实际工时,再从根往下递归:父任务进度 = 子任务加权,工时相加。根任务算完后,把加权进度写回台账 progress。
已取消的叶子不自动改状态。叶子全部 100% 且完成 / 归档,父任务才跟着重算。超期未完成标延期。项目经理不该在父任务格子里手填一个「看起来合理」的百分比。
4. 甘特:同一棵树的时间条
台账 Tab「甘特图」读任务的计划起止和进度。拖条、改日期会回刷任务看板和里程碑,避免甘特和 WBS 各改各的。申请单上的甘特是草案预览;现场以台账甘特为准。
▲ 同一 id=18,切到甘特图。条是任务,不是项目经理另画的一张图
三、设计怎么落地
设计思路
|
|
|
|
|---|---|---|
|
|
project_info
project_ledger
|
|
|
|
沿用申请单 id |
|
|
|
onProcessApproved |
|
|
|
|
|
|
|
|
|
申请单状态:0 草稿、1 审批中、2 已立项。台账通过后进进行中(2)。任务树用 parent_id,根是 0。
提交先改审批中再启流程。通过才物化。进度从执行记录往上卷,最后写台账一行。
public Long submitProjectInfo(ProjectInfoSaveReqVO saveReqVO) {Long id = saveProjectInfo(saveReqVO);ProjectInfoDO projectInfo = projectInfoMapper.selectById(id);projectInfo.setStatus(STATUS_APPROVING); // 1 审批中projectInfo.setProcessStatus(BpmTaskStatusEnum.RUNNING.getStatus());String processInstanceId = processInstanceApi.submitProcessInstance(..., new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey("project_create").setBusinessKey(String.valueOf(id))).getCheckedData();projectInfo.setProcessInstanceId(processInstanceId);projectInfoMapper.updateById(projectInfo);return id;}
通过回调冻结申请单,并物化台账。台账主键故意等于申请单,详情路由不用再翻译。
public void onProcessApproved(String businessKey) {Long id = Long.parseLong(businessKey);ProjectInfoDO project = validateProjectInfoExists(id);projectInfoMapper.updateById(new ProjectInfoDO().setId(id).setStatus(STATUS_APPROVED)); // 2 已立项projectLedgerService.upsertFromDraft(project, LEDGER_STATUS_IN_PROGRESS);initLedgerMembers(project);}
upsertFromDraft 拷字段、写 draftProjectId、必要时回填合同预算。已有行就更新,避免通过回调重入插两条。
public ProjectLedgerDO upsertFromDraft(ProjectInfoDO draft, Integer status) {ProjectLedgerDO ledger = BeanUtils.toBean(draft, ProjectLedgerDO.class);ledger.setId(draft.getId());ledger.setDraftProjectId(draft.getId());ledger.setStatus(status);if (draft.getContractId() != null && draft.getBudgetAmount() == null) {// 合同总额回填预算基线}if (projectLedgerMapper.selectById(ledger.getId()) == null) {projectLedgerMapper.insert(ledger);} else {projectLedgerMapper.updateById(ledger);}return ledger;}
上卷先处理叶子执行,再递归父节点,最后把根的加权进度写回台账。父任务没有自己的「拍脑袋百分比」。
四、和「Excel 甘特」差在哪
|
|
|
|
|---|---|---|
|
|
|
|
|
|
ledger.id = info.id |
|
|
|
|
|
|
|
|
|
|
|
onProcessRejected |
|
资料库可以在物化时 ensureSpace,但验收这条链时先看:申请单已立项、台账打得开、任务能上卷、甘特条和任务对得上。
五、快速体验
在线演示:https://ruoyioffice.com/web/(账号 admin / admin123)
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
源码仓库:GitHub:https://github.com/yuqing2026/ruoyi-office | GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office | Gitee:https://gitee.com/yqzy1688/ruoyi-office
常见问题
立项通过后还能改申请单吗?
产品上申请单已冻结。要改预算、经理、范围,应走变更,不要把已立项单当草稿改。驳回的单才退回草稿。
为什么台账 id 不另生成?
另生成就要处处映射:权限、文档空间、甘特、动态。沿用申请单 id,路由 /project/project-ledger-detail?id= 和立项 id 对得上。
父任务进度能不能手填?
上卷会按子任务加权覆盖。手填只在下一次填报之前看起来对。要调整体进度,改叶子执行或拆任务。
申请页也有甘特,和台账甘特有何不同?
申请页是草案预览,给审批人看计划长什么样。台账甘特跟执行走,拖条回写任务。现场以台账为准。
和项目文档协同是不是同一篇文章?
不是。文档树、ACL、在线编辑是资料空间。本文只保证立项冻结和进度能解释。两套可以同时开,不要用文件夹代替 WBS。
结语
立项链能跑住,靠的是:通过才冻结,台账沿用同一 id,进度从叶子往上卷。 甘特是这棵树的视图,不是第二本计划。Excel 条形图管不住的,是「申请口径」和「现场口径」什么时候分开。
同一套「单据冻结 → 台账物化 → 明细上卷」还可以用在预算编制对执行台账、销售订单对出库进度。先把项目这一条走通,再谈看板和盈利分析。
💡 想要体验 RuoYi Office 的强大功能?
🌐 在线演示:https://ruoyioffice.com/web/(账号 admin / admin123)
📦 源码仓库:GitHub:https://github.com/yuqing2026/ruoyi-office | GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office | Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 技术咨询:添加微信 17156169080,备注「RuoYi Office」
⭐ 如果觉得不错,请给个 Star 支持一下!

