Skip to content

15:项目评估:多明细保存与 BPM 审批

1. 项目评估在业务链中的位置

项目评估是对某条客户产品跟进进行交付、风险、成本和规则判断的审批单。

text
customer_product_follow(必须正在跟进)
  -> project_evaluation(主表)
  -> 风险/服务需求/结算规则/人员类型/垫资用途/保险说明(明细)
  -> 附件
  -> BPM 审批

2. 真实入口与表

文件 / 方法
ControllerProjectEvaluationController
FormProjectEvaluationAddForm、编辑 Form
DTOProjectEvaluationDto
ServiceProjectEvaluationServiceImpl.insertProjectEvaluationupdateProjectEvaluationfindByIdupdateFlowProgress
主表project_evaluation
明细project_evaluation_risk_contentproject_evaluation_service_requirementproject_evaluation_settlement_ruleproject_evaluation_personnel_typeproject_evaluation_advance_payment_purposeproject_evaluation_insurance_instruction
附件sys_file

3. 新增项目评估的真实代码顺序

源码 insertProjectEvaluation(ProjectEvaluationDto dto) 使用事务。业务顺序:

text
1. 读取当前用户 openId 和主部门
2. 查询 dto.productFollowId 对应的 CustomerProductFollow
3. 不存在 -> “客户产品跟进信息不存在”
4. followStatus 不是 FOLLOWING -> 禁止创建评估
5. 当前用户不是该产品跟进人 -> 禁止创建评估
6. 从跟进记录复制 productId、followerOpenId、followerDepartmentId
7. 生成 projectNumber,初始 flowStatus = PENDING,设置创建部门
8. 保存 project_evaluation 主表
9. 批量保存六类明细
10. 按附件类型写 sys_file(罚则、报价)
11. 调 SaasBpmModelServer.startFlow 发起审批
12. 回写 flowId、IN_PROGRESS、flowStartTime

前 6 步是“业务准入校验”;后 6 步才是持久化和流程交互。不要调换顺序。

4. 明细表的维护模式

项目评估的每类明细都有一个独立 Service,例如:

text
ProjectEvaluationRiskContentServiceImpl
ProjectEvaluationServiceRequirementServiceImpl
ProjectEvaluationSettlementRuleServiceImpl
ProjectEvaluationPersonnelTypeServiceImpl
ProjectEvaluationAdvancePaymentPurposeServiceImpl
ProjectEvaluationInsuranceInstructionServiceImpl

它们的模式高度一致:

text
batchInsertXxx(evaluationId, list)
batchUpdateXxx(evaluationId, list)
getByEvaluationId(evaluationId)

batchUpdateXxx 的语义是“以请求内容替换该评估的此类明细”,而不是只修改一条。实现时必须明确删旧建新还是差量更新,并处于同一事务。

5. 编辑与详情

编辑 updateProjectEvaluation

text
1. 评估主表必须存在
2. 关联产品跟进必须仍存在且处于 FOLLOWING
3. 从产品跟进同步产品、跟进人和部门
4. 更新主表
5. 依次批量更新六类明细

详情 findById

text
主表 -> ProjectEvaluationVo
  + 结算规则列表
  + 风险、服务需求、人员类型、垫资用途
  + 按保险类型分组的说明
  + 附件
  + 关联跟进/客户/产品展示信息

6. BPM 回调就是状态机

表中保存 flowIdflowStatus。流程状态更新由:

java
updateFlowProgress(String flowId, String status)

完成。你需要把外部流程状态映射为内部 FlowStatusEnum,并避免对已终态单据重复处理。

Demo 可先模拟:

text
PENDING -> IN_PROGRESS -> APPROVED / REJECTED

不要在 Demo 一开始接 BPM;先提供一个内部接口模拟审批结果回调。

7. Demo 实现版本

先只保留:

text
demo_customer_product_follow
demo_project_evaluation
demo_project_evaluation_risk

实现:

text
创建评估前:follow 状态必须 FOLLOWING,当前用户必须是模拟跟进人
保存:评估主表 + 多条风险明细,在一个事务中
发起:status = IN_PROGRESS
回调:按 evaluationId 修改 APPROVED / REJECTED

然后再逐步加结算规则、人员类型、附件和更多明细。

8. 必测用例

  • 跟进不存在,不能创建评估;
  • 跟进已过期/已入公海,不能创建评估;
  • 不是跟进人,不能创建评估;
  • 明细其中一条保存失败,主表和全部明细回滚;
  • 流程发起成功后,flowId 和状态正确回写;
  • 回调后审批状态正确;
  • 详情能聚合全部明细。

9. 源码阅读顺序

text
ProjectEvaluationController
ProjectEvaluationAddForm
ProjectEvaluationConverter
ProjectEvaluationServiceImpl.insertProjectEvaluation
ProjectEvaluationServiceImpl.updateProjectEvaluation
ProjectEvaluationServiceImpl.findById
ProjectEvaluationServiceImpl.updateFlowProgress
六个 ProjectEvaluation*ServiceImpl
pginit.sql 中 project_evaluation 及六张明细表

Lucking