Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yanxuan-qc-change-system
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yx-qc-change-flow
yanxuan-qc-change-system
Commits
5443ba39
Commit
5443ba39
authored
Dec 03, 2025
by
王志超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 子工单分批流转逻辑处理
parent
5e45ca3d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
65 additions
and
76 deletions
+65
-76
ChangeFlowBiz.java
...om/netease/mail/yanxuan/change/biz/biz/ChangeFlowBiz.java
+50
-31
ChangeSubFlowBiz.java
...netease/mail/yanxuan/change/biz/biz/ChangeSubFlowBiz.java
+15
-45
No files found.
yanxuan-qc-change-system-biz/src/main/java/com/netease/mail/yanxuan/change/biz/biz/ChangeFlowBiz.java
View file @
5443ba39
...
@@ -704,24 +704,9 @@ public class ChangeFlowBiz {
...
@@ -704,24 +704,9 @@ public class ChangeFlowBiz {
buildAndSendEmail
.
buildAndSendEmailSubmit
(
changeRecord
,
changeExecRecords
);
buildAndSendEmail
.
buildAndSendEmailSubmit
(
changeRecord
,
changeExecRecords
);
return
submitNode
;
return
submitNode
;
case
NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN:
case
NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN:
// 确认变更方案节点:检查所有子单是否都已审批通过
// 确认变更方案节点:由子单审批通过后自动触发,不应该由前端主动调用
if
(!
checkAllSubFlowsApprovedForMainFlow
(
changeRecord
.
getId
()))
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"该节点不允许主动提交,需等待所有子单审批通过后自动流转"
);
"存在子单未审批通过,无法流转主工单"
);
}
// 所有子单都已审批通过,流转主工单到部门负责人审批节点
String
ownerApproveNodeId
=
flowService
.
submitFlow
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
true
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"所有子单审批通过,主工单流转"
,
changeRecord
.
getCreateTime
());
changeRecord
.
setFlowNode
(
ownerApproveNodeId
);
changeRecord
.
setState
(
ChangeStatusEnum
.
WAIT_DEPT_LEADER_APPROVE
.
getStatus
());
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN] 主工单流转成功,flowId:{}, nextNodeId:{}"
,
flowId
,
ownerApproveNodeId
);
return
ownerApproveNodeId
;
case
NEW_CHANGE_FLOW_OWNER_APPROVE:
case
NEW_CHANGE_FLOW_OWNER_APPROVE:
case
NEW_CHANGE_FLOW_ADMIN_APPROVE:
case
NEW_CHANGE_FLOW_ADMIN_APPROVE:
case
NEW_CHANGE_FLOW_QUALITY_APPROVE:
case
NEW_CHANGE_FLOW_QUALITY_APPROVE:
...
@@ -1739,24 +1724,58 @@ public class ChangeFlowBiz {
...
@@ -1739,24 +1724,58 @@ public class ChangeFlowBiz {
}
}
/**
/**
*
检查主工单下所有子单是否都已审批通过(供主工单流转时调用)
*
所有子单审批通过后,流转主工单到部门负责人审批节点
*
条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
*
从 NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN 流转到 NEW_CHANGE_FLOW_OWNER_APPROVE
*
*
* @param changeRecordId 主工单ID
* @param changeRecordId 主工单ID
* @return true 表示所有子单都已审批通过
*/
*/
public
boolean
checkAllSubFlowsApprovedForMainFlow
(
Long
changeRecordId
)
{
void
submitMainFlowAfterAllSubFlowsApproved
(
Long
changeRecordId
)
{
// 查询该主工单下所有子单
// 查询主工单
List
<
ChangeSubFlowRecord
>
allSubFlows
=
changeSubFlowRecordMapper
.
selectByChangeRecordId
(
changeRecordId
);
ChangeRecord
changeRecord
=
changeRecordMapper
.
selectByPrimaryKey
(
changeRecordId
);
if
(
CollectionUtils
.
isEmpty
(
allSubFlows
))
{
if
(
changeRecord
==
null
)
{
return
false
;
log
.
error
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单不存在,changeRecordId:{}"
,
changeRecordId
);
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"主工单不存在"
);
}
}
// 检查是否所有子单都满足条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
// 验证主工单当前节点
return
allSubFlows
.
stream
().
allMatch
(
subFlow
->
String
currentNode
=
changeRecord
.
getFlowNode
();
ChangeFlowEnum
.
CHANGE_SUB_FLOW_EXE
.
getNodeId
().
equals
(
subFlow
.
getSubFlowNode
())
if
(!
ChangeFlowEnum
.
NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN
.
getNodeId
().
equals
(
currentNode
))
{
&&
Boolean
.
TRUE
.
equals
(
subFlow
.
getChangePlanApproved
())
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
NODE_ERROR
,
);
String
.
format
(
"主工单当前节点不是确认变更方案节点,无法流转。当前节点:%s"
,
currentNode
));
}
try
{
Long
flowId
=
changeRecord
.
getFlowId
();
String
uid
=
RequestLocalBean
.
getUid
();
// 获取工单详情
FlowDataDTO
flowDataDTO
=
flowService
.
flowDetail
(
flowId
.
toString
());
if
(
flowDataDTO
==
null
)
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
DETAIL_FLOW_ERROR
,
"工单查询错误,不存在"
);
}
// 构建提交内容
Map
<
String
,
Object
>
content
=
new
HashMap
<>(
CommonConstants
.
INIT_HASH_MAP_SIZE
);
content
.
put
(
"updateTime"
,
System
.
currentTimeMillis
());
content
.
put
(
CommonConstants
.
FLOW_OPERATION_KEY
,
FlowOperationTypeEnum
.
PASS
.
getValue
());
// 流转主工单到部门负责人审批节点
String
ownerApproveNodeId
=
flowService
.
submitFlow
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
true
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"所有子单审批通过,主工单流转"
,
changeRecord
.
getCreateTime
());
changeRecord
.
setFlowNode
(
ownerApproveNodeId
);
changeRecord
.
setState
(
ChangeStatusEnum
.
WAIT_DEPT_LEADER_APPROVE
.
getStatus
());
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单流转成功,flowId:{}, nextNodeId:{}"
,
flowId
,
ownerApproveNodeId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单流转失败,changeRecordId:{}"
,
changeRecordId
,
e
);
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
String
.
format
(
"主工单流转失败:%s"
,
e
.
getMessage
()));
}
}
}
/**
/**
...
...
yanxuan-qc-change-system-biz/src/main/java/com/netease/mail/yanxuan/change/biz/biz/ChangeSubFlowBiz.java
View file @
5443ba39
...
@@ -33,7 +33,6 @@ import com.netease.mail.yanxuan.change.dal.mapper.ChangeSubFlowRecordMapper;
...
@@ -33,7 +33,6 @@ import com.netease.mail.yanxuan.change.dal.mapper.ChangeSubFlowRecordMapper;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeExecConfigReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeExecConfigReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowSubmitReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowCreateReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowCreateReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowListQueryReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowListQueryReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowSubmitReq
;
import
com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowSubmitReq
;
...
@@ -299,28 +298,17 @@ public class ChangeSubFlowBiz {
...
@@ -299,28 +298,17 @@ public class ChangeSubFlowBiz {
changeSubFlowRecordService
.
update
(
subFlowRecord
);
changeSubFlowRecordService
.
update
(
subFlowRecord
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 审批不通过,subFlowId:{}, rejectReason:{}"
,
subFlowId
,
execRejectReason
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 审批不通过,subFlowId:{}, rejectReason:{}"
,
subFlowId
,
execRejectReason
);
}
else
{
}
else
{
// 审批通过,只标记 changePlanApproved=true,
暂不更新状态和流转工单
// 审批通过,只标记 changePlanApproved=true,
子单不流转
subFlowRecord
.
setChangePlanApproved
(
true
);
subFlowRecord
.
setChangePlanApproved
(
true
);
subFlowRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
subFlowRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeSubFlowRecordService
.
update
(
subFlowRecord
);
changeSubFlowRecordService
.
update
(
subFlowRecord
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 审批通过,subFlowId:{}, 标记changePlanApproved=true"
,
subFlowId
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 审批通过,subFlowId:{}, 标记changePlanApproved=true"
,
subFlowId
);
// 检查该主工单下所有子单是否都已审批通过
// 检查该主工单下所有子单是否都已审批通过
if
(
changeFlowBiz
.
checkAllSubFlowsApprovedForMainFlow
(
subFlowRecord
.
getChangeRecordId
()))
{
if
(
checkAllSubFlowsApproved
(
subFlowRecord
.
getChangeRecordId
()))
{
// 所有子单都通过,批量流转所有子单并更新状态
// 所有子单都通过,流转主工单
batchSubmitAllSubFlows
(
subFlowRecord
.
getChangeRecordId
(),
flowDataDTO
,
uid
,
content
);
changeFlowBiz
.
submitMainFlowAfterAllSubFlowsApproved
(
subFlowRecord
.
getChangeRecordId
());
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 所有子单均已审批通过,批量流转子单到下一节点"
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 所有子单均已审批通过,主工单已流转"
);
// 所有子单流转完成后,流转主工单
ChangeRecord
mainRecord
=
changeRecordMapper
.
selectByPrimaryKey
(
subFlowRecord
.
getChangeRecordId
());
if
(
mainRecord
!=
null
)
{
ChangeFlowSubmitReq
mainFlowSubmitReq
=
new
ChangeFlowSubmitReq
();
mainFlowSubmitReq
.
setFlowId
(
mainRecord
.
getFlowId
());
mainFlowSubmitReq
.
setCurrentNodeId
(
mainRecord
.
getFlowNode
());
changeFlowBiz
.
submit
(
mainFlowSubmitReq
);
log
.
info
(
"[CHANGE_SUB_FLOW_EXE] 主工单流转成功,changeRecordId:{}, flowId:{}"
,
subFlowRecord
.
getChangeRecordId
(),
mainRecord
.
getFlowId
());
}
}
}
}
}
...
@@ -502,42 +490,24 @@ public class ChangeSubFlowBiz {
...
@@ -502,42 +490,24 @@ public class ChangeSubFlowBiz {
}
}
/**
/**
* 批量流转所有子单到下一节点,并流转主工单
* 检查主工单下所有子单是否都已审批通过
* 条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
*
*
* @param changeRecordId 主工单ID
* @param changeRecordId 主工单ID
* @param flowDataDTO 流程数据
* @return true 表示所有子单都已审批通过
* @param uid 操作人
* @param content 内容
*/
*/
private
void
batchSubmitAllSubFlows
(
Long
changeRecordId
,
FlowDataDTO
flowDataDTO
,
String
uid
,
Object
content
)
{
private
boolean
checkAllSubFlowsApproved
(
Long
changeRecordId
)
{
// 查询该主工单下所有子单
// 查询该主工单下所有子单
List
<
ChangeSubFlowRecord
>
allSubFlows
=
changeSubFlowRecordMapper
.
selectByChangeRecordId
(
changeRecordId
);
List
<
ChangeSubFlowRecord
>
allSubFlows
=
changeSubFlowRecordMapper
.
selectByChangeRecordId
(
changeRecordId
);
if
(
CollectionUtils
.
isEmpty
(
allSubFlows
))
{
if
(
CollectionUtils
.
isEmpty
(
allSubFlows
))
{
return
;
return
false
;
}
}
// 批量流转所有子单
// 检查是否所有子单都满足条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
for
(
ChangeSubFlowRecord
subFlow
:
allSubFlows
)
{
return
allSubFlows
.
stream
().
allMatch
(
subFlow
->
try
{
ChangeFlowEnum
.
CHANGE_SUB_FLOW_EXE
.
getNodeId
().
equals
(
subFlow
.
getSubFlowNode
())
// 提交子单流程到下一节点
&&
Boolean
.
TRUE
.
equals
(
subFlow
.
getChangePlanApproved
())
String
nextNodeId
=
flowService
.
submitFlow
(
subFlow
.
getSubFlowId
(),
flowDataDTO
,
uid
,
);
ChangeFlowEnum
.
CHANGE_SUB_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
true
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"所有子单审批通过,自动流转"
,
subFlow
.
getCreateTime
());
// 更新子单节点和状态
subFlow
.
setSubFlowNode
(
nextNodeId
);
subFlow
.
setStatus
(
ChangeSubFlowStatusEnum
.
WAIT_SUBMIT_RESULT
.
getStatus
());
subFlow
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeSubFlowRecordService
.
update
(
subFlow
);
log
.
info
(
"[batchSubmitAllSubFlows] 子单流转成功,subFlowId:{}, nextNodeId:{}"
,
subFlow
.
getSubFlowId
(),
nextNodeId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[batchSubmitAllSubFlows] 子单流转失败,subFlowId:{}"
,
subFlow
.
getSubFlowId
(),
e
);
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
String
.
format
(
"子单[%s]流转失败:%s"
,
subFlow
.
getSubFlowId
(),
e
.
getMessage
()));
}
}
}
}
/**
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment