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
c8fc33d3
Commit
c8fc33d3
authored
Dec 05, 2025
by
王志超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 统一处理主单审批节点的流转逻辑
parent
a240240c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
329 additions
and
46 deletions
+329
-46
ChangeFlowBiz.java
...om/netease/mail/yanxuan/change/biz/biz/ChangeFlowBiz.java
+306
-46
AppConfig.java
...com/netease/mail/yanxuan/change/biz/config/AppConfig.java
+12
-0
FlowTransitionType.java
...l/yanxuan/change/common/constants/FlowTransitionType.java
+5
-0
ChangeFlowSubmitReq.java
...anxuan/change/dal/meta/model/req/ChangeFlowSubmitReq.java
+6
-0
No files found.
yanxuan-qc-change-system-biz/src/main/java/com/netease/mail/yanxuan/change/biz/biz/ChangeFlowBiz.java
View file @
c8fc33d3
...
...
@@ -711,55 +711,44 @@ public class ChangeFlowBiz {
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"该节点不允许主动提交,需等待所有子单审批通过后自动流转"
);
case
NEW_CHANGE_FLOW_OWNER_APPROVE:
case
NEW_CHANGE_FLOW_ADMIN_APPROVE:
case
NEW_CHANGE_FLOW_QUALITY_APPROVE:
// 部门负责人、变更管理员、质量部负责人审批节点
Boolean
mainFlowApproved
=
changeFlowSubmitReq
.
getApproved
();
if
(
mainFlowApproved
==
null
)
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"审批结果不能为空"
);
}
// 部门负责人审批节点:设置下一个审批人为变更管理员
String
changeAdmin
=
appConfig
.
getChangeAdmin
();
Map
<
String
,
Object
>
ownerApproveParamMap
=
new
HashMap
<>();
ownerApproveParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_APPROVED
);
return
handleMainFlowApprovalSubmit
(
changeFlowSubmitReq
,
flowId
,
flowDataDTO
,
uid
,
changeRecord
,
node
,
content
,
ownerApproveParamMap
,
changeAdmin
,
ChangeStatusEnum
.
WAIT_CHANGE_ADMIN_APPROVE
);
// 使用paramMap控制流转方向
Map
<
String
,
Object
>
mainFlowParamMap
=
new
HashMap
<>();
String
mainFlowNodeId
;
case
NEW_CHANGE_FLOW_ADMIN_APPROVE:
// 变更管理员审批节点:根据变更等级判断下一步
// 重要变更(changeLevel=1):需要质量部负责人审批,type=1
// 一般变更(changeLevel=2):跳过质量部审批,直接到执行变更方案,type=4
Integer
changeLevel
=
changeRecord
.
getChangeLevel
();
Map
<
String
,
Object
>
adminApproveParamMap
=
new
HashMap
<>();
String
nextApproverForAdmin
;
ChangeStatusEnum
nextStatusForAdmin
;
if
(
mainFlowApproved
)
{
// 审批通过:流转到下一节点
log
.
info
(
"[{}] 审批通过,flowId:{}"
,
node
.
getName
(),
flowId
);
mainFlowParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_APPROVED
);
mainFlowNodeId
=
flowService
.
submitFlowWithParamMap
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
mainFlowParamMap
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"审批通过"
,
changeRecord
.
getCreateTime
());
// 更新主工单记录
changeRecord
.
setFlowNode
(
mainFlowNodeId
);
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[checkUpdateAndSubmit] 主工单流转完成,flowId:{}, 审批节点:{}, 新节点:{}, 审批结果:通过"
,
flowId
,
node
.
getName
(),
mainFlowNodeId
);
if
(
ChangeLevelEnum
.
IMPORTANT
.
getType
().
equals
(
changeLevel
))
{
// 重要变更:走质量部负责人审批
adminApproveParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_APPROVED
);
nextApproverForAdmin
=
appConfig
.
getChangeQualityLeader
();
nextStatusForAdmin
=
ChangeStatusEnum
.
WAIT_QUALITY_LEADER_APPROVE
;
log
.
info
(
"[NEW_CHANGE_FLOW_ADMIN_APPROVE] 重要变更,需要质量部负责人审批"
);
}
else
{
// 审批不通过:回退到确认变更方案节点
// todo: 实现审批不通过的逻辑(拒绝原因、状态更新、邮件通知等)
log
.
warn
(
"[{}] 审批不通过,flowId:{}"
,
node
.
getName
(),
flowId
);
mainFlowParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_BACK_TO_CONFIRM_PLAN
);
mainFlowNodeId
=
flowService
.
submitFlowWithParamMap
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
mainFlowParamMap
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"审批不通过"
,
changeRecord
.
getCreateTime
());
// 更新主工单记录(回到确认变更方案节点)
changeRecord
.
setFlowNode
(
mainFlowNodeId
);
changeRecord
.
setState
(
ChangeStatusEnum
.
WAIT_CONFIRM_CHANGE_PLAN
.
getStatus
());
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[checkUpdateAndSubmit] 主工单流转完成,flowId:{}, 审批节点:{}, 新节点:确认变更方案, 审批结果:不通过"
,
flowId
,
node
.
getName
());
// 一般变更:跳过质量部负责人审批
adminApproveParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_SKIP_QUALITY_APPROVE
);
nextApproverForAdmin
=
null
;
nextStatusForAdmin
=
ChangeStatusEnum
.
WAIT_EXEC_CHANGE_PLAN
;
log
.
info
(
"[NEW_CHANGE_FLOW_ADMIN_APPROVE] 一般变更,跳过质量部负责人审批"
);
}
return
handleMainFlowApprovalSubmit
(
changeFlowSubmitReq
,
flowId
,
flowDataDTO
,
uid
,
changeRecord
,
node
,
content
,
adminApproveParamMap
,
nextApproverForAdmin
,
nextStatusForAdmin
);
return
mainFlowNodeId
;
case
NEW_CHANGE_FLOW_QUALITY_APPROVE:
// 质量部负责人审批节点:审批通过后流转到执行变更方案
Map
<
String
,
Object
>
qualityApproveParamMap
=
new
HashMap
<>();
qualityApproveParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_APPROVED
);
return
handleMainFlowApprovalSubmit
(
changeFlowSubmitReq
,
flowId
,
flowDataDTO
,
uid
,
changeRecord
,
node
,
content
,
qualityApproveParamMap
,
null
,
ChangeStatusEnum
.
WAIT_EXEC_CHANGE_PLAN
);
case
NEW_CHANGE_FLOW_EXE:
// 执行变更方案节点:等待所有子单完成后自动流转,不允许主动提交
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
...
...
@@ -1613,6 +1602,97 @@ public class ChangeFlowBiz {
*
* @param changeRecordId 主工单ID
*/
/**
* 统一处理主单审批节点的流转逻辑(包含审批通过和审批不通过)
*
* @param changeFlowSubmitReq 提交请求
* @param flowId 工单ID
* @param flowDataDTO 工单详情
* @param uid 当前用户
* @param changeRecord 主工单记录
* @param node 当前节点
* @param content 提交内容
* @param approvedParamMap 审批通过时的 paramMap
* @param nextApprover 下一个审批人邮箱(可选,为空则不设置)
* @param nextStatus 下一个状态(可选,为空则不设置)
* @return 下一节点ID
*/
private
String
handleMainFlowApprovalSubmit
(
ChangeFlowSubmitReq
changeFlowSubmitReq
,
Long
flowId
,
FlowDataDTO
flowDataDTO
,
String
uid
,
ChangeRecord
changeRecord
,
ChangeFlowEnum
node
,
Map
<
String
,
Object
>
content
,
Map
<
String
,
Object
>
approvedParamMap
,
String
nextApprover
,
ChangeStatusEnum
nextStatus
)
{
Boolean
approved
=
changeFlowSubmitReq
.
getApproved
();
if
(
approved
==
null
)
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"审批结果不能为空"
);
}
String
nextNodeId
;
if
(
approved
)
{
// 审批通过:流转到下一节点
log
.
info
(
"[{}] 审批通过,flowId:{}"
,
node
.
getName
(),
flowId
);
nextNodeId
=
flowService
.
submitFlowWithParamMap
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
approvedParamMap
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"审批通过"
,
changeRecord
.
getCreateTime
());
// 更新主工单记录
changeRecord
.
setFlowNode
(
nextNodeId
);
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
// 设置下一个审批人(如果提供)
if
(
StringUtils
.
isNotBlank
(
nextApprover
))
{
changeRecord
.
setApprover
(
JSON
.
toJSONString
(
Collections
.
singletonList
(
nextApprover
)));
log
.
info
(
"[{}] 下一个审批人:{}"
,
node
.
getName
(),
nextApprover
);
}
// 设置下一个状态(如果提供)
if
(
nextStatus
!=
null
)
{
changeRecord
.
setState
(
nextStatus
.
getStatus
());
}
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[checkUpdateAndSubmit] 主工单流转完成,flowId:{}, 审批节点:{}, 新节点:{}, 审批结果:通过"
,
flowId
,
node
.
getName
(),
nextNodeId
);
}
else
{
// 审批不通过:回退到确认变更方案节点,并取消所有子单
log
.
warn
(
"[{}] 审批不通过,flowId:{}"
,
node
.
getName
(),
flowId
);
Map
<
String
,
Object
>
rejectParamMap
=
new
HashMap
<>();
rejectParamMap
.
put
(
"type"
,
FlowTransitionType
.
TYPE_BACK_TO_CONFIRM_PLAN
);
nextNodeId
=
flowService
.
submitFlowWithParamMap
(
flowId
.
toString
(),
flowDataDTO
,
uid
,
ChangeFlowEnum
.
NEW_CHANGE_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
content
),
rejectParamMap
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"审批不通过"
,
changeRecord
.
getCreateTime
());
// 更新主工单记录(回到确认变更方案节点)
changeRecord
.
setFlowNode
(
nextNodeId
);
changeRecord
.
setState
(
ChangeStatusEnum
.
WAIT_CONFIRM_CHANGE_PLAN
.
getStatus
());
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeFlowService
.
updateRecord
(
changeRecord
);
// 取消指定的子单(审批人选择要取消的行动工单)
String
rejectReason
=
changeFlowSubmitReq
.
getRejectReason
();
if
(
StringUtils
.
isBlank
(
rejectReason
))
{
rejectReason
=
"主单审批不通过"
;
}
List
<
String
>
cancelSubFlowIds
=
changeFlowSubmitReq
.
getCancelSubFlowIds
();
int
cancelledCount
=
0
;
if
(
CollectionUtils
.
isNotEmpty
(
cancelSubFlowIds
))
{
cancelledCount
=
cancelSelectedSubFlows
(
changeRecord
.
getId
(),
cancelSubFlowIds
,
rejectReason
);
}
// 发送审批不通过邮件通知
sendMainFlowRejectEmail
(
changeRecord
,
node
.
getName
(),
rejectReason
,
cancelledCount
);
log
.
info
(
"[checkUpdateAndSubmit] 主工单流转完成,flowId:{}, 审批节点:{}, 新节点:确认变更方案, 审批结果:不通过,已取消子单数:{}"
,
flowId
,
node
.
getName
(),
cancelledCount
);
}
return
nextNodeId
;
}
void
submitMainFlowAfterAllSubFlowsApproved
(
Long
changeRecordId
)
{
// 查询主工单
ChangeRecord
changeRecord
=
changeRecordMapper
.
selectByPrimaryKey
(
changeRecordId
);
...
...
@@ -1655,10 +1735,23 @@ public class ChangeFlowBiz {
changeRecord
.
setFlowNode
(
ownerApproveNodeId
);
changeRecord
.
setState
(
ChangeStatusEnum
.
WAIT_DEPT_LEADER_APPROVE
.
getStatus
());
changeRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
// 获取变更负责人的上级领导并设置为审批人
String
changeCommander
=
changeRecord
.
getChangeCommander
();
if
(
StringUtils
.
isBlank
(
changeCommander
))
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
"变更负责人邮箱不能为空"
);
}
String
leaderEmail
=
departmentLeaderBiz
.
getDepartmentLeader
(
changeCommander
);
if
(
StringUtils
.
isBlank
(
leaderEmail
))
{
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
String
.
format
(
"变更负责人[%s]的部门上级领导不存在"
,
changeCommander
));
}
// 设置审批人为上级领导(JSON 数组格式)
changeRecord
.
setApprover
(
JSON
.
toJSONString
(
Collections
.
singletonList
(
leaderEmail
)));
changeFlowService
.
updateRecord
(
changeRecord
);
log
.
info
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单流转成功,flowId:{}, nextNodeId:{}"
,
flowId
,
ownerApproveNodeId
);
log
.
info
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单流转成功,flowId:{}, nextNodeId:{}
, approver:{}
"
,
flowId
,
ownerApproveNodeId
,
leaderEmail
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[submitMainFlowAfterAllSubFlowsApproved] 主工单流转失败,changeRecordId:{}"
,
changeRecordId
,
e
);
throw
ExceptionFactory
.
createBiz
(
ResponseCode
.
BAD_REQUEST
,
...
...
@@ -1686,5 +1779,172 @@ public class ChangeFlowBiz {
||
ChangeSubFlowStatusEnum
.
CANCELLED
.
getStatus
().
equals
(
subFlow
.
getStatus
())
);
}
/**
* 发送主单审批不通过邮件通知
*
* @param changeRecord 主工单记录
* @param rejectNodeName 审批不通过的节点名称
* @param rejectReason 拒绝原因
* @param cancelledCount 取消的子单数量
*/
private
void
sendMainFlowRejectEmail
(
ChangeRecord
changeRecord
,
String
rejectNodeName
,
String
rejectReason
,
int
cancelledCount
)
{
try
{
// 构建邮件参数
Map
<
String
,
Object
>
emailParam
=
new
HashMap
<>();
emailParam
.
put
(
"changeId"
,
changeRecord
.
getFlowId
());
emailParam
.
put
(
"changeSubject"
,
ChangeSubjectEnum
.
getChangeSubjectEnum
(
changeRecord
.
getChangeSubject
()).
getDesc
());
// 构建变更类型
ChangeType
parentChangeType
=
changeTypeService
.
getChangeTypeById
(
changeRecord
.
getParentChangeClassId
());
ChangeType
sonChangeType
=
changeTypeService
.
getChangeTypeById
(
changeRecord
.
getSonChangeClassId
());
if
(
parentChangeType
!=
null
&&
sonChangeType
!=
null
)
{
emailParam
.
put
(
"changeType"
,
parentChangeType
.
getTypeName
()
+
">"
+
sonChangeType
.
getTypeName
());
}
emailParam
.
put
(
"changeContent"
,
changeRecord
.
getChangeContent
());
emailParam
.
put
(
"rejectNodeName"
,
rejectNodeName
);
emailParam
.
put
(
"rejectReason"
,
rejectReason
);
emailParam
.
put
(
"cancelledSubFlowCount"
,
cancelledCount
);
emailParam
.
put
(
"flowUrl"
,
changeRecord
.
getFlowId
());
String
subjectParam
=
changeRecord
.
getFlowId
().
toString
();
// 收件人:变更负责人、变更发起人
List
<
String
>
receiver
=
new
ArrayList
<>();
String
changeCommander
=
changeRecord
.
getChangeCommander
();
receiver
.
add
(
changeCommander
);
String
creator
=
changeRecord
.
getCreator
();
if
(!
creator
.
equals
(
changeCommander
))
{
receiver
.
add
(
creator
);
}
// 抄送人:变更负责人上一级主管、变更管理QM、所有行动人
List
<
String
>
ccList
=
new
ArrayList
<>();
ccList
.
addAll
(
departmentLeaderBiz
.
getDepartmentLeaders
(
Collections
.
singletonList
(
changeCommander
)));
ccList
.
add
(
appConfig
.
getChangeManageQM
());
// 添加所有行动人到抄送列表
List
<
ChangeFlowExecVO
>
execRecord
=
changeFlowExecService
.
getChangeFlowExecRecord
(
changeRecord
.
getId
());
if
(
CollectionUtils
.
isNotEmpty
(
execRecord
))
{
List
<
String
>
execUserEmails
=
execRecord
.
stream
()
.
map
(
ChangeFlowExecVO:
:
getChangeExecUserEmail
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toList
());
ccList
.
addAll
(
execUserEmails
);
}
// 发送邮件(使用"发起变更"模板,因为需要重新提交)
qcSendEmail
(
receiver
,
ccList
,
subjectParam
,
EmailTemplateEnum
.
YX_QC_CHANGE_RELEASE_FLOW
,
emailParam
);
// 如果是供应商相关,发送供应商邮件
if
(
CreateSourceEnum
.
TONG_ZHOU
.
getType
().
equals
(
changeRecord
.
getCreateSource
()))
{
sendSupplierEmail
.
sendSupplierEmail
(
changeRecord
.
getCreateSupplier
(),
subjectParam
,
EmailTemplateEnum
.
YX_QC_CHANGE_RELEASE_FLOW
,
emailParam
);
}
else
if
(
ChangeSubjectEnum
.
SUPPLIER
.
getType
().
equals
(
changeRecord
.
getChangeSubject
()))
{
sendSupplierEmail
.
sendSupplierEmail
(
changeRecord
.
getChangeSupplier
(),
subjectParam
,
EmailTemplateEnum
.
YX_QC_CHANGE_RELEASE_FLOW
,
emailParam
);
}
log
.
info
(
"[sendMainFlowRejectEmail] 审批不通过邮件已发送,flowId:{}, rejectNode:{}"
,
changeRecord
.
getFlowId
(),
rejectNodeName
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[sendMainFlowRejectEmail] 发送审批不通过邮件失败,flowId:{}, error:{}"
,
changeRecord
.
getFlowId
(),
e
.
getMessage
(),
e
);
}
}
/**
* 取消主工单下指定的子单(主单审批不通过时调用)
*
* @param changeRecordId 主工单ID
* @param cancelSubFlowIds 要取消的子单ID列表
* @param cancelReason 取消原因
* @return 实际取消的子单数量
*/
private
int
cancelSelectedSubFlows
(
Long
changeRecordId
,
List
<
String
>
cancelSubFlowIds
,
String
cancelReason
)
{
if
(
CollectionUtils
.
isEmpty
(
cancelSubFlowIds
))
{
log
.
info
(
"[cancelSelectedSubFlows] 未指定要取消的子单,changeRecordId:{}"
,
changeRecordId
);
return
0
;
}
// 查询该主工单下所有子单
List
<
ChangeSubFlowRecord
>
allSubFlows
=
changeSubFlowRecordMapper
.
selectByChangeRecordId
(
changeRecordId
);
if
(
CollectionUtils
.
isEmpty
(
allSubFlows
))
{
log
.
info
(
"[cancelSelectedSubFlows] 主工单没有子单,changeRecordId:{}"
,
changeRecordId
);
return
0
;
}
// 过滤出要取消的子单
List
<
ChangeSubFlowRecord
>
subFlowsToCancel
=
allSubFlows
.
stream
()
.
filter
(
subFlow
->
cancelSubFlowIds
.
contains
(
subFlow
.
getSubFlowId
()))
.
collect
(
Collectors
.
toList
());
if
(
CollectionUtils
.
isEmpty
(
subFlowsToCancel
))
{
log
.
warn
(
"[cancelSelectedSubFlows] 未找到要取消的子单,changeRecordId:{}, cancelSubFlowIds:{}"
,
changeRecordId
,
cancelSubFlowIds
);
return
0
;
}
log
.
info
(
"[cancelSelectedSubFlows] 开始取消指定子单,changeRecordId:{}, 待取消数量:{}, 总数量:{}, 取消原因:{}"
,
changeRecordId
,
subFlowsToCancel
.
size
(),
allSubFlows
.
size
(),
cancelReason
);
int
cancelledCount
=
0
;
int
skippedCount
=
0
;
for
(
ChangeSubFlowRecord
subFlowRecord
:
subFlowsToCancel
)
{
Integer
currentStatus
=
subFlowRecord
.
getStatus
();
String
subFlowId
=
subFlowRecord
.
getSubFlowId
();
// 跳过已完成或已取消的子单
if
(
ChangeSubFlowStatusEnum
.
FINISHED
.
getStatus
().
equals
(
currentStatus
)
||
ChangeSubFlowStatusEnum
.
CANCELLED
.
getStatus
().
equals
(
currentStatus
))
{
log
.
info
(
"[cancelAllSubFlows] 子单已完成或已取消,跳过, subFlowId:{}, status:{}"
,
subFlowId
,
currentStatus
);
skippedCount
++;
continue
;
}
try
{
// 查询子单流程详情
FlowDataDTO
subFlowDataDTO
=
flowService
.
flowDetail
(
subFlowId
);
if
(
subFlowDataDTO
==
null
)
{
log
.
warn
(
"[cancelAllSubFlows] 子单流程查询失败,跳过, subFlowId:{}"
,
subFlowId
);
skippedCount
++;
continue
;
}
// 构建提交内容
Map
<
String
,
Object
>
cancelContent
=
new
HashMap
<>(
CommonConstants
.
INIT_HASH_MAP_SIZE
);
cancelContent
.
put
(
"updateTime"
,
System
.
currentTimeMillis
());
cancelContent
.
put
(
CommonConstants
.
FLOW_OPERATION_KEY
,
FlowOperationTypeEnum
.
REFUSE
.
getValue
());
// 提交子单流程到结束节点(取消)
String
cancelNodeId
=
flowService
.
submitFlow
(
subFlowId
,
subFlowDataDTO
,
RequestLocalBean
.
getUid
(),
ChangeFlowEnum
.
CHANGE_SUB_FLOW
.
getTopoId
(),
JSON
.
toJSONString
(
cancelContent
),
false
,
FlowxOperationEnum
.
SUBMIT
.
getName
(),
"主单审批不通过,自动取消"
,
subFlowRecord
.
getCreateTime
());
// 更新子单记录
subFlowRecord
.
setSubFlowNode
(
cancelNodeId
);
subFlowRecord
.
setStatus
(
ChangeSubFlowStatusEnum
.
CANCELLED
.
getStatus
());
subFlowRecord
.
setCancelReason
(
cancelReason
);
subFlowRecord
.
setUpdateTime
(
DateUtils
.
getCurrentTime
());
changeSubFlowRecordService
.
update
(
subFlowRecord
);
cancelledCount
++;
log
.
info
(
"[cancelAllSubFlows] 子单已取消, subFlowId:{}, nodeId:{}"
,
subFlowId
,
cancelNodeId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[cancelAllSubFlows] 取消子单失败, subFlowId:{}, error:{}"
,
subFlowId
,
e
.
getMessage
(),
e
);
// 继续取消下一个子单,不中断整个流程
}
}
log
.
info
(
"[cancelSelectedSubFlows] 子单取消完成,changeRecordId:{}, 待取消数:{}, 已取消:{}, 跳过:{}"
,
changeRecordId
,
subFlowsToCancel
.
size
(),
cancelledCount
,
skippedCount
);
return
cancelledCount
;
}
}
yanxuan-qc-change-system-biz/src/main/java/com/netease/mail/yanxuan/change/biz/config/AppConfig.java
View file @
c8fc33d3
...
...
@@ -95,6 +95,18 @@ public class AppConfig {
*/
@Value
(
"${changeManageQM:cuiyixian@corp.netease.com}"
)
private
String
changeManageQM
;
/**
* 变更管理员(用于主单审批流程)
*/
@Value
(
"${changeAdmin:}"
)
private
String
changeAdmin
;
/**
* 质量部负责人(用于主单审批流程)
*/
@Value
(
"${changeQualityLeader:}"
)
private
String
changeQualityLeader
;
/**
* 变更管理委员会
...
...
yanxuan-qc-change-system-common/src/main/java/com/netease/mail/yanxuan/change/common/constants/FlowTransitionType.java
View file @
c8fc33d3
...
...
@@ -24,6 +24,11 @@ public class FlowTransitionType {
*/
public
static
final
Integer
TYPE_BACK_TO_CONFIRM_PLAN
=
3
;
/**
* 类型4:跳过质量部负责人审批,直接到执行变更方案节点(一般变更专用)
*/
public
static
final
Integer
TYPE_SKIP_QUALITY_APPROVE
=
4
;
private
FlowTransitionType
()
{
// 工具类,禁止实例化
}
...
...
yanxuan-qc-change-system-dal/src/main/java/com/netease/mail/yanxuan/change/dal/meta/model/req/ChangeFlowSubmitReq.java
View file @
c8fc33d3
...
...
@@ -130,4 +130,9 @@ public class ChangeFlowSubmitReq {
* 拒绝原因(审批不通过时必填)
*/
private
String
rejectReason
;
/**
* 要取消的子单ID列表(审批不通过时,选择要取消的行动工单)
*/
private
List
<
String
>
cancelSubFlowIds
;
}
\ No newline at end of file
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