Browse Source

Merge remote-tracking branch 'origin/master'

master
yanyan 2 months ago
parent
commit
3b36120447
  1. 12
      src/main/java/com/xujie/modules/workFlow/entity/ErfFlowNodeInstance.java
  2. 24
      src/main/java/com/xujie/modules/workFlow/mapper/ErfFlowInstanceMapper.java
  3. 118
      src/main/java/com/xujie/modules/workFlow/service/impl/ErfFlowInstanceServiceImpl.java
  4. 57
      src/main/resources/mapper/workFlow/ErfFlowInstanceMapper.xml

12
src/main/java/com/xujie/modules/workFlow/entity/ErfFlowNodeInstance.java

@ -12,7 +12,7 @@ import java.util.Date;
/**
* 节点实例实体类审批记录 - rqrq
* 复合主键apply_no + node_code + attempt_no + site + order_type
* 复合主键apply_no + node_code + attempt_no + task_seq + site + order_type
*/
@Data
@Alias("ErfFlowNodeInstance")
@ -34,6 +34,11 @@ public class ErfFlowNodeInstance extends QueryPage {
*/
private Integer attemptNo;
/**
* 同一节点同一轮次下的任务序号会签/或签多审批人时每行递增主键之一 - rqrq
*/
private Integer taskSeq;
/**
* 工厂编码主键之一
*/
@ -59,6 +64,11 @@ public class ErfFlowNodeInstance extends QueryPage {
*/
private Long assigneeUserId;
/**
* 审批人登录名 erf_flow_node_approver.approver_username 一致用于待办匹配 - rqrq
*/
private String assigneeUsername;
/**
* 审批人姓名
*/

24
src/main/java/com/xujie/modules/workFlow/mapper/ErfFlowInstanceMapper.java

@ -58,8 +58,9 @@ public interface ErfFlowInstanceMapper extends BaseMapper<ErfFlowInstance> {
* 更新节点实例状态
*/
void updateNodeInstanceStatus(@Param("applyNo") String applyNo, @Param("nodeCode") String nodeCode,
@Param("attemptNo") Integer attemptNo, @Param("site") String site, @Param("orderType") String orderType,
@Param("status") String status, @Param("comment") String comment, @Param("specialRelease") String specialRelease);
@Param("attemptNo") Integer attemptNo, @Param("taskSeq") Integer taskSeq, @Param("site") String site,
@Param("orderType") String orderType, @Param("status") String status, @Param("comment") String comment,
@Param("specialRelease") String specialRelease);
/**
* 获取节点实例详情
@ -80,10 +81,25 @@ public interface ErfFlowInstanceMapper extends BaseMapper<ErfFlowInstance> {
@Param("site") String site, @Param("orderType") String orderType);
/**
* 获取待审批的节点实例
* 获取待审批的节点实例按当前登录用户名/展示名匹配审批人 - rqrq
*/
ErfFlowNodeInstanceData getPendingNodeInstance(@Param("applyNo") String applyNo, @Param("nodeCode") String nodeCode,
@Param("site") String site, @Param("orderType") String orderType);
@Param("site") String site, @Param("orderType") String orderType,
@Param("assigneeUsername") String assigneeUsername, @Param("assigneeDisplayName") String assigneeDisplayName);
/**
* 统计节点当前轮次下仍为待办的任务数 - rqrq
*/
int countPendingNodeTasks(@Param("applyNo") String applyNo, @Param("nodeCode") String nodeCode,
@Param("attemptNo") Integer attemptNo, @Param("site") String site, @Param("orderType") String orderType);
/**
* 将同节点同轮次下除指定序号外的待办任务批量更新为指定状态 - rqrq
*/
void updateOtherPendingNodeTasks(@Param("applyNo") String applyNo, @Param("nodeCode") String nodeCode,
@Param("attemptNo") Integer attemptNo, @Param("site") String site, @Param("orderType") String orderType,
@Param("excludeTaskSeq") Integer excludeTaskSeq, @Param("newStatus") String newStatus,
@Param("comment") String comment);
/**
* 删除指定单据的所有节点实例 - rqrq

118
src/main/java/com/xujie/modules/workFlow/service/impl/ErfFlowInstanceServiceImpl.java

@ -21,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 流程实例Service实现类 - rqrq
@ -90,12 +89,6 @@ public class ErfFlowInstanceServiceImpl extends ServiceImpl<ErfFlowInstanceMappe
throw new RuntimeException("流程配置错误:未找到审批节点");
}
// 获取审批人
List<ErfFlowNodeApproverData> approverList = erfFlowTemplateMapper.getApproverListByNodeId(firstApproveNode.getId());
if (approverList == null || approverList.isEmpty()) {
throw new RuntimeException("流程配置错误:审批节点未配置审批人");
}
// 创建流程实例 - rqrq
ErfFlowInstance instance = new ErfFlowInstance();
instance.setApplyNo(applyNo);
@ -108,23 +101,8 @@ public class ErfFlowInstanceServiceImpl extends ServiceImpl<ErfFlowInstanceMappe
instance.setCurrentNodeCode(firstApproveNode.getNodeCode());
erfFlowInstanceMapper.insertInstance(instance);
// 创建节点实例为每个审批人创建一条记录
for (ErfFlowNodeApproverData approver : approverList) {
ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance();
nodeInstance.setApplyNo(applyNo);
nodeInstance.setNodeCode(firstApproveNode.getNodeCode());
nodeInstance.setAttemptNo(1);
nodeInstance.setSite(site);
nodeInstance.setOrderType(orderType);
// 设置部门信息从节点配置获取- rqrq
nodeInstance.setDepartmentId(firstApproveNode.getDepartmentId());
nodeInstance.setDepartmentName(firstApproveNode.getDepartmentName());
// 需要通过username查找用户ID
nodeInstance.setAssigneeName(approver.getApproverName());
nodeInstance.setStatus("PENDING");
nodeInstance.setSpecialRelease("N");
erfFlowInstanceMapper.insertNodeInstance(nodeInstance);
}
//创建节点实例会签/或签为每个审批人一行主键含 task_seq - rqrq
insertPendingNodeInstances(applyNo, site, orderType, 1, firstApproveNode);
System.out.println("创建流程实例结束");
return applyNo;
@ -149,30 +127,47 @@ public class ErfFlowInstanceServiceImpl extends ServiceImpl<ErfFlowInstanceMappe
throw new RuntimeException("流程实例不存在");
}
// 获取待审批的节点实例
// 获取当前登录用户对应的待审批任务会签多人时按用户名匹配 - rqrq
ErfFlowNodeInstanceData nodeInstance = erfFlowInstanceMapper.getPendingNodeInstance(
data.getApplyNo(), data.getNodeCode(), data.getSite(), data.getOrderType());
data.getApplyNo(), data.getNodeCode(), data.getSite(), data.getOrderType(),
operator, currentUserDisplay);
if (nodeInstance == null) {
throw new RuntimeException("未找到待审批的节点");
}
// 校验当前用户是否是审批人 - rqrq
if (nodeInstance.getAssigneeName() != null && !nodeInstance.getAssigneeName().equals(currentUserDisplay)) {
if (nodeInstance.getAssigneeUsername() != null && !nodeInstance.getAssigneeUsername().equals(operator)) {
throw new RuntimeException("您不是该节点的审批人,无法进行审批操作");
}
if (nodeInstance.getAssigneeUsername() == null && nodeInstance.getAssigneeName() != null
&& !nodeInstance.getAssigneeName().equals(currentUserDisplay)) {
throw new RuntimeException("您不是该节点的审批人,无法进行审批操作");
}
// 更新节点实例状态含特殊放行标记- rqrq
erfFlowInstanceMapper.updateNodeInstanceStatus(
data.getApplyNo(), data.getNodeCode(), nodeInstance.getAttemptNo(),
data.getApplyNo(), data.getNodeCode(), nodeInstance.getAttemptNo(), nodeInstance.getTaskSeq(),
data.getSite(), data.getOrderType(), data.getAction(), data.getComment(), data.getSpecialRelease());
// 处理审批结果
if ("APPROVED".equals(data.getAction())) {
// 激活下一个节点
String approveType = nodeInstance.getApproveType() != null ? nodeInstance.getApproveType() : "SINGLE";
nodeInstance.setSpecialRelease(data.getSpecialRelease());
activateNextNode(instance, nodeInstance);
if ("ALL".equals(approveType)) {
int pendingLeft = erfFlowInstanceMapper.countPendingNodeTasks(data.getApplyNo(), data.getNodeCode(),
nodeInstance.getAttemptNo(), data.getSite(), data.getOrderType());
if (pendingLeft == 0) {
activateNextNode(instance, nodeInstance);
}
} else if ("ANY".equals(approveType)) {
erfFlowInstanceMapper.updateOtherPendingNodeTasks(data.getApplyNo(), data.getNodeCode(),
nodeInstance.getAttemptNo(), data.getSite(), data.getOrderType(), nodeInstance.getTaskSeq(),
"SKIPPED", "或签:已有他人审批通过");
activateNextNode(instance, nodeInstance);
} else {
activateNextNode(instance, nodeInstance);
}
} else if ("REJECTED".equals(data.getAction())) {
// 终止流程
erfFlowInstanceMapper.updateOtherPendingNodeTasks(data.getApplyNo(), data.getNodeCode(),
nodeInstance.getAttemptNo(), data.getSite(), data.getOrderType(), nodeInstance.getTaskSeq(),
"CANCELLED", "节点已驳回,任务关闭");
erfFlowInstanceMapper.updateInstanceStatus(
data.getApplyNo(), data.getSite(), data.getOrderType(),
"TERMINATED", nodeInstance.getNodeCode());
@ -208,20 +203,33 @@ public class ErfFlowInstanceServiceImpl extends ServiceImpl<ErfFlowInstanceMappe
erfFlowInstanceMapper.updateInstanceStatus(instance.getApplyNo(), instance.getSite(),
instance.getOrderType(), "RUNNING", nextNode.getNodeCode());
// 获取审批人并创建节点实例
List<ErfFlowNodeApproverData> approverList = erfFlowTemplateMapper.getApproverListByNodeId(nextNode.getId());
insertPendingNodeInstances(instance.getApplyNo(), instance.getSite(), instance.getOrderType(), 1, nextNode);
}
/**
* 按节点定义生成待办任务行每人一行 - rqrq
*/
private void insertPendingNodeInstances(String applyNo, String site, String orderType, int attemptNo,
ErfFlowNodeData node) {
List<ErfFlowNodeApproverData> approverList = erfFlowTemplateMapper.getApproverListByNodeId(node.getId());
if (approverList == null || approverList.isEmpty()) {
throw new RuntimeException("流程配置错误:审批节点未配置审批人");
}
int taskSeq = 1;
for (ErfFlowNodeApproverData approver : approverList) {
ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance();
nodeInstance.setApplyNo(instance.getApplyNo());
nodeInstance.setNodeCode(nextNode.getNodeCode());
nodeInstance.setAttemptNo(1);
nodeInstance.setSite(instance.getSite());
nodeInstance.setOrderType(instance.getOrderType());
// 设置部门信息从节点配置获取- rqrq
nodeInstance.setDepartmentId(nextNode.getDepartmentId());
nodeInstance.setDepartmentName(nextNode.getDepartmentName());
nodeInstance.setApplyNo(applyNo);
nodeInstance.setNodeCode(node.getNodeCode());
nodeInstance.setAttemptNo(attemptNo);
nodeInstance.setTaskSeq(taskSeq++);
nodeInstance.setSite(site);
nodeInstance.setOrderType(orderType);
nodeInstance.setDepartmentId(node.getDepartmentId());
nodeInstance.setDepartmentName(node.getDepartmentName());
nodeInstance.setAssigneeUsername(approver.getApproverUsername());
nodeInstance.setAssigneeName(approver.getApproverName());
nodeInstance.setStatus("PENDING");
nodeInstance.setSpecialRelease("N");
erfFlowInstanceMapper.insertNodeInstance(nodeInstance);
}
}
@ -296,33 +304,13 @@ public class ErfFlowInstanceServiceImpl extends ServiceImpl<ErfFlowInstanceMappe
throw new RuntimeException("流程配置错误:未找到审批节点");
}
// 获取审批人
List<ErfFlowNodeApproverData> approverList = erfFlowTemplateMapper.getApproverListByNodeId(firstApproveNode.getId());
if (approverList == null || approverList.isEmpty()) {
throw new RuntimeException("流程配置错误:审批节点未配置审批人");
}
// 删除原有的所有节点实例
erfFlowInstanceMapper.deleteNodeInstancesByApplyNo(applyNo, site, orderType);
// 重置流程实例状态
erfFlowInstanceMapper.restartInstance(applyNo, site, orderType, firstApproveNode.getNodeCode());
// 创建第一个节点实例为每个审批人创建一条记录
for (ErfFlowNodeApproverData approver : approverList) {
ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance();
nodeInstance.setApplyNo(applyNo);
nodeInstance.setNodeCode(firstApproveNode.getNodeCode());
nodeInstance.setAttemptNo(1);
nodeInstance.setSite(site);
nodeInstance.setOrderType(orderType);
// 设置部门信息从节点配置获取- rqrq
nodeInstance.setDepartmentId(firstApproveNode.getDepartmentId());
nodeInstance.setDepartmentName(firstApproveNode.getDepartmentName());
nodeInstance.setAssigneeName(approver.getApproverName());
nodeInstance.setStatus("PENDING");
erfFlowInstanceMapper.insertNodeInstance(nodeInstance);
}
insertPendingNodeInstances(applyNo, site, orderType, 1, firstApproveNode);
System.out.println("重新审批流程实例结束");
}

57
src/main/resources/mapper/workFlow/ErfFlowInstanceMapper.xml

@ -44,16 +44,18 @@
</select>
<!-- 查询节点实例列表 -->
<select id="searchNodeInstanceList" resultType="ErfFlowNodeInstanceData">
<select id="searchNodeInstanceList" resultType="ErfFlowNodeInstanceData">
SELECT
ni.apply_no,
ni.node_code,
ni.attempt_no,
ni.task_seq,
ni.site,
ni.order_type,
ni.department_id,
ni.department_name,
ni.assignee_user_id,
ni.assignee_username,
ni.assignee_name,
ni.status,
ni.comment,
@ -61,7 +63,6 @@
ni.receive_time,
ni.complete_time,
ni.duration_seconds,
ni.special_release,
n.node_name,
n.node_order,
n.approve_type
@ -72,7 +73,7 @@
WHERE ni.apply_no = #{applyNo}
AND ni.site = #{site}
AND ni.order_type = #{orderType}
ORDER BY n.node_order, ni.attempt_no
ORDER BY n.node_order, ni.attempt_no, ni.task_seq
</select>
<!-- 插入流程实例 - rqrq -->
@ -87,13 +88,14 @@
</insert>
<!-- 插入节点实例 -->
<!-- rqrq -插入节点实例(含 task_seq、assignee_username,支持会签/或签多行) -->
<insert id="insertNodeInstance">
INSERT INTO erf_flow_node_instance (
apply_no, node_code, attempt_no, site, order_type,
department_id, department_name, assignee_user_id, assignee_name, status, receive_time
apply_no, node_code, attempt_no, task_seq, site, order_type,
department_id, department_name, assignee_user_id, assignee_username, assignee_name, status, receive_time
) VALUES (
#{applyNo}, #{nodeCode}, #{attemptNo}, #{site}, #{orderType},
#{departmentId}, #{departmentName}, #{assigneeUserId}, #{assigneeName}, #{status}, GETDATE()
#{applyNo}, #{nodeCode}, #{attemptNo}, #{taskSeq}, #{site}, #{orderType},
#{departmentId}, #{departmentName}, #{assigneeUserId}, #{assigneeUsername}, #{assigneeName}, #{status}, GETDATE()
)
</insert>
@ -127,6 +129,7 @@
WHERE apply_no = #{applyNo}
AND node_code = #{nodeCode}
AND attempt_no = #{attemptNo}
AND task_seq = #{taskSeq}
AND site = #{site}
AND order_type = #{orderType}
</update>
@ -137,9 +140,11 @@
ni.apply_no,
ni.node_code,
ni.attempt_no,
ni.task_seq,
ni.site,
ni.order_type,
ni.assignee_user_id,
ni.assignee_username,
ni.assignee_name,
ni.status,
ni.comment,
@ -194,14 +199,17 @@
</select>
<!-- 获取待审批的节点实例 -->
<!-- rqrq - 待办按审批人精确匹配,避免会签多人时取错行 -->
<select id="getPendingNodeInstance" resultType="ErfFlowNodeInstanceData">
SELECT TOP 1
ni.apply_no,
ni.node_code,
ni.attempt_no,
ni.task_seq,
ni.site,
ni.order_type,
ni.assignee_user_id,
ni.assignee_username,
ni.assignee_name,
ni.status,
ni.special_release,
@ -218,9 +226,40 @@
AND ni.site = #{site}
AND ni.order_type = #{orderType}
AND ni.status = 'PENDING'
ORDER BY ni.attempt_no DESC
AND (
(ni.assignee_username IS NOT NULL AND ni.assignee_username = #{assigneeUsername})
OR (ni.assignee_username IS NULL AND ni.assignee_name = #{assigneeDisplayName})
)
ORDER BY ni.attempt_no DESC, ni.task_seq ASC
</select>
<!-- rqrq - 当前节点轮次待办数量 -->
<select id="countPendingNodeTasks" resultType="int">
SELECT COUNT(1)
FROM erf_flow_node_instance
WHERE apply_no = #{applyNo}
AND node_code = #{nodeCode}
AND attempt_no = #{attemptNo}
AND site = #{site}
AND order_type = #{orderType}
AND status = 'PENDING'
</select>
<!-- rqrq - 批量关闭同节点其他待办(或签跳过 / 驳回关闭) -->
<update id="updateOtherPendingNodeTasks">
UPDATE erf_flow_node_instance
SET status = #{newStatus},
comment = #{comment},
complete_time = GETDATE()
WHERE apply_no = #{applyNo}
AND node_code = #{nodeCode}
AND attempt_no = #{attemptNo}
AND site = #{site}
AND order_type = #{orderType}
AND status = 'PENDING'
AND task_seq &lt;&gt; #{excludeTaskSeq}
</update>
<!-- 删除指定单据的所有节点实例 - rqrq -->
<delete id="deleteNodeInstancesByApplyNo">
@ -247,9 +286,11 @@
ni.apply_no,
ni.node_code,
ni.attempt_no,
ni.task_seq,
ni.site,
ni.order_type,
ni.assignee_user_id,
ni.assignee_username,
ni.assignee_name,
ni.status,
ni.comment,

Loading…
Cancel
Save