From dc5e5c07549b493e21c11dc7929c32ea9fd732b0 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期四, 08 十月 2026 17:08:26 +0800
Subject: [PATCH] 协同办公系统模块优化

---
 src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java |  283 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 208 insertions(+), 75 deletions(-)

diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
index 04adc4b..39d93af 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -3,21 +3,31 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.approve.mapper.ApproveLogMapper;
 import com.ruoyi.approve.mapper.ApproveNodeMapper;
+import com.ruoyi.approve.mapper.ApproveProcessMapper;
+import com.ruoyi.approve.pojo.ApproveLog;
 import com.ruoyi.approve.pojo.ApproveNode;
 import com.ruoyi.approve.pojo.ApproveProcess;
 import com.ruoyi.approve.service.IApproveNodeService;
-import com.ruoyi.approve.service.IApproveProcessService;
+import com.ruoyi.approve.vo.ApproveNodeVO;
+import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.other.service.impl.TempFileServiceImpl;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
-import lombok.AllArgsConstructor;
+import com.ruoyi.sales.mapper.CommonFileMapper;
+import com.ruoyi.sales.pojo.CommonFile;
 import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
+import java.io.IOException;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
@@ -25,92 +35,215 @@
 @Service
 @RequiredArgsConstructor
 public class ApproveNodeServiceImpl extends ServiceImpl<ApproveNodeMapper, ApproveNode> implements IApproveNodeService {
+    private final ApproveNodeMapper approveNodeMapper;
+    private final ApproveProcessMapper approveProcessMapper;
+    private final ApproveLogMapper approveLogMapper;
+    private final SysUserMapper sysUserMapper;
+    private final TempFileServiceImpl tempFileService;
+    private final CommonFileMapper fileMapper;
 
-    @Autowired
-    private  ApproveNodeMapper approveNodeMapper;
-    @Autowired
-    private  IApproveProcessService approveProcessService;
-    @Autowired
-    private SysUserMapper sysUserMapper;
-
+    private ApproveProcess getApproveById(String code) {
+        ApproveProcess process = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>()
+                .eq(ApproveProcess::getApproveId, code)
+                .eq(ApproveProcess::getApproveDelete, 0)
+                .eq(ApproveProcess::getTenantId, tenantId())
+                .last("limit 1"));
+        if (process == null) throw new RuntimeException("瀹℃壒涓嶅瓨鍦�");
+        return process;
+    }
 
     @Override
-    public void initApproveNodes(String approveUserIds,String approveID,Long tenantId) {
-        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
-        ApproveProcess approve = approveProcessService.getApproveById(approveID);
-        String[] names = approveUserIds.split(",");
-        String approveId = approve.getApproveId();
-        for (int i = 0; i < names.length; i++) {
-            SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(names[i]));
-            if (sysUser == null) continue;
-            ApproveNode approveNode = new ApproveNode();
-            approveNode.setApproveProcessId(approveId);
-            approveNode.setApproveNodeOrder(i +1);
-            approveNode.setApproveNodeUser(sysUser.getNickName());
-            approveNode.setApproveNodeUserId(sysUser.getUserId());
-            approveNode.setApproveNodeTime(new Date());
-            approveNode.setApproveNodeStatus(0);
-            approveNode.setTenantId(tenantId);
-            approveNode.setDeleteFlag(0);
-            approveNode.setCreateUser(userId);
-            approveNode.setUpdateUser(userId);
-            approveNode.setCreateTime(LocalDateTime.now());
-            approveNode.setUpdateTime(LocalDateTime.now());
-            approveNodeMapper.insert(approveNode);
+    public void initApproveNodes(String approveUserIds, String approveID, Long tenantId) {
+        if (!StringUtils.hasText(approveUserIds)) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
+        List<ApproveNodeVO> nodes = new ArrayList<>();
+        for (String id : approveUserIds.split(",")) {
+            ApproveNodeVO node = new ApproveNodeVO();
+            node.setUserId(Long.parseLong(id.trim()));
+            node.setConditionOperator("ALWAYS");
+            nodes.add(node);
         }
+        initApproveNodes(nodes, approveID, tenantId);
+    }
+
+    @Override
+    public void initApproveNodes(List<ApproveNodeVO> nodes, String approveID, Long ignoredTenantId) {
+        if (CollectionUtils.isEmpty(nodes)) throw new RuntimeException("瀹℃壒娴佺▼鑷冲皯鍖呭惈涓�涓妭鐐�");
+        Long tenantId = tenantId();
+        Long currentUserId = SecurityUtils.getUserId();
+        ApproveProcess process = getApproveById(approveID);
+        int order = 1;
+        ApproveNode first = null;
+        Long previousUserId = null;
+        for (ApproveNodeVO request : nodes) {
+            if (request.getUserId() == null) throw new RuntimeException("瀹℃壒浜轰笉鑳戒负绌�");
+            if (request.getUserId().equals(previousUserId)) throw new RuntimeException("鐩搁偦瀹℃壒鑺傜偣涓嶈兘閫夋嫨鍚屼竴瀹℃壒浜�");
+            previousUserId = request.getUserId();
+            if (!matchesCondition(process.getAmount(), request)) continue;
+            SysUser user = sysUserMapper.selectUserById(request.getUserId());
+            if (user == null || !tenantId.equals(user.getTenantId())) throw new RuntimeException("瀹℃壒浜轰笉瀛樺湪鎴栦笉灞炰簬褰撳墠绉熸埛");
+            ApproveNode node = new ApproveNode();
+            node.setApproveProcessId(process.getApproveId());
+            node.setApproveNodeOrder(order++);
+            node.setApproveNodeName(StringUtils.hasText(request.getNodeName()) ? request.getNodeName() : "瀹℃壒");
+            node.setApproveNodeUser(user.getNickName());
+            node.setApproveNodeUserId(user.getUserId());
+            node.setApproveNodeStatus(0);
+            node.setConditionField(request.getConditionField());
+            node.setConditionOperator(StringUtils.hasText(request.getConditionOperator()) ? request.getConditionOperator() : "ALWAYS");
+            node.setConditionValue(request.getConditionValue());
+            node.setIsCurrent(first == null ? 1 : 0);
+            node.setTenantId(tenantId);
+            node.setDeleteFlag(0);
+            node.setCreateUser(currentUserId);
+            node.setUpdateUser(currentUserId);
+            node.setCreateTime(LocalDateTime.now());
+            node.setUpdateTime(LocalDateTime.now());
+            approveNodeMapper.insert(node);
+            if (first == null) first = node;
+        }
+        if (first == null) throw new RuntimeException("娌℃湁婊¤冻鏉′欢鐨勫鎵硅妭鐐�");
+        process.setApproveUserCurrentId(first.getApproveNodeUserId());
+        process.setApproveUserCurrentName(first.getApproveNodeUser());
+        process.setUpdateTime(LocalDateTime.now());
+        approveProcessMapper.updateById(process);
+    }
+
+    private boolean matchesCondition(BigDecimal amount, ApproveNodeVO node) {
+        String operator = node.getConditionOperator();
+        if (!StringUtils.hasText(operator) || "ALWAYS".equalsIgnoreCase(operator)) return true;
+        if (!"amount".equals(node.getConditionField())) throw new RuntimeException("瀹℃壒鏉′欢浠呮敮鎸侀噾棰濆瓧娈�");
+        if (amount == null || !StringUtils.hasText(node.getConditionValue())) return false;
+        try {
+            if ("BETWEEN".equalsIgnoreCase(operator)) {
+                String[] values = node.getConditionValue().replace("[", "").replace("]", "").split(",");
+                if (values.length != 2) throw new RuntimeException("閲戦鍖洪棿鏍煎紡涓嶆纭�");
+                return amount.compareTo(new BigDecimal(values[0].trim())) >= 0
+                        && amount.compareTo(new BigDecimal(values[1].trim())) <= 0;
+            }
+            int compared = amount.compareTo(new BigDecimal(node.getConditionValue()));
+            if ("GT".equalsIgnoreCase(operator)) return compared > 0;
+            if ("GTE".equalsIgnoreCase(operator)) return compared >= 0;
+            if ("LT".equalsIgnoreCase(operator)) return compared < 0;
+            if ("LTE".equalsIgnoreCase(operator)) return compared <= 0;
+            if ("EQ".equalsIgnoreCase(operator)) return compared == 0;
+        } catch (NumberFormatException ex) {
+            throw new RuntimeException("瀹℃壒鏉′欢閲戦鏍煎紡涓嶆纭�");
+        }
+        throw new RuntimeException("涓嶆敮鎸佺殑瀹℃壒鏉′欢鎿嶄綔绗�");
     }
 
     @Override
     public List<ApproveNode> details(String id) {
-        LambdaQueryWrapper<ApproveNode> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(ApproveNode::getApproveProcessId, id);
-        queryWrapper.eq(ApproveNode::getDeleteFlag, 0);
-        queryWrapper.eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId());
-        List<ApproveNode> list = list(queryWrapper);
-        // 鎸夌収 approveNodeOrder 瀛楁鍗囧簭鎺掑簭
-        list.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder));
-        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, id)
-                .eq(ApproveProcess::getApproveDelete, 0)
-                .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())
-                .last("limit 1");
-        ApproveProcess approveProcess = approveProcessService.getOne(approveProcessLambdaQueryWrapper);
-        if(approveProcess != null && approveProcess.getApproveStatus() == 3){
-            return list;
+        getApproveById(id);
+        List<ApproveNode> nodes = approveNodeMapper.selectList(new LambdaQueryWrapper<ApproveNode>()
+                .eq(ApproveNode::getApproveProcessId, id)
+                .eq(ApproveNode::getDeleteFlag, 0)
+                .eq(ApproveNode::getTenantId, tenantId())
+                .orderByAsc(ApproveNode::getApproveNodeOrder));
+        for (ApproveNode node : nodes) {
+            List<CommonFile> files = fileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                    .eq(CommonFile::getCommonId, node.getId())
+                    .eq(CommonFile::getType, FileNameType.ApproveNode.getValue()));
+            if (!CollectionUtils.isEmpty(files)) node.setUrl(files.get(0).getUrl());
+            node.setIsShen(Integer.valueOf(1).equals(node.getIsCurrent())
+                    && node.getApproveNodeUserId().equals(SecurityUtils.getUserId()));
         }
-        for (ApproveNode approveNode : list) {
-            if(approveNode.getApproveNodeStatus() == 1){
-                continue;
+        nodes.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder));
+        return nodes;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateApproveNode(ApproveNode request) throws IOException {
+        if (request == null || request.getId() == null) throw new RuntimeException("瀹℃壒鑺傜偣涓嶈兘涓虹┖");
+        if (request.getApproveNodeStatus() == null || (request.getApproveNodeStatus() != 1 && request.getApproveNodeStatus() != 2)) {
+            throw new RuntimeException("瀹℃壒缁撴灉涓嶆纭�");
+        }
+        if (!StringUtils.hasText(request.getApproveNodeReason())) throw new RuntimeException("瀹℃壒鎰忚涓嶈兘涓虹┖");
+        Long tenantId = tenantId();
+        ApproveNode node = approveNodeMapper.selectOne(new LambdaQueryWrapper<ApproveNode>()
+                .eq(ApproveNode::getId, request.getId())
+                .eq(ApproveNode::getTenantId, tenantId)
+                .eq(ApproveNode::getDeleteFlag, 0));
+        if (node == null) throw new RuntimeException("瀹℃壒鑺傜偣涓嶅瓨鍦�");
+        if (!Integer.valueOf(0).equals(node.getApproveNodeStatus()) || !Integer.valueOf(1).equals(node.getIsCurrent())) {
+            throw new RuntimeException("璇ヨ妭鐐瑰凡缁忓鐞嗘垨涓嶆槸褰撳墠瀹℃壒鑺傜偣");
+        }
+        if (!SecurityUtils.getUserId().equals(node.getApproveNodeUserId())) throw new RuntimeException("褰撳墠鐢ㄦ埛鏃犳潈瀹℃壒姝よ妭鐐�");
+
+        ApproveProcess process = getApproveById(node.getApproveProcessId());
+        if (Integer.valueOf(2).equals(process.getApproveStatus()) || Integer.valueOf(3).equals(process.getApproveStatus())) {
+            throw new RuntimeException("瀹℃壒娴佺▼宸茬粡缁撴潫");
+        }
+        node.setApproveNodeStatus(request.getApproveNodeStatus());
+        node.setApproveNodeReason(request.getApproveNodeReason().trim());
+        node.setApproveNodeRemark(request.getApproveNodeRemark());
+        node.setApproveNodeTime(new Date());
+        node.setIsCurrent(0);
+        node.setUpdateUser(SecurityUtils.getUserId());
+        node.setUpdateTime(LocalDateTime.now());
+        approveNodeMapper.updateById(node);
+
+        if (node.getApproveNodeStatus() == 2) {
+            process.setApproveStatus(3);
+            process.setApproveUserCurrentId(null);
+            process.setApproveUserCurrentName(null);
+            process.setApproveOverTime(new Date());
+        } else {
+            ApproveNode next = approveNodeMapper.selectOne(new LambdaQueryWrapper<ApproveNode>()
+                    .eq(ApproveNode::getApproveProcessId, node.getApproveProcessId())
+                    .eq(ApproveNode::getTenantId, tenantId)
+                    .eq(ApproveNode::getDeleteFlag, 0)
+                    .eq(ApproveNode::getApproveNodeStatus, 0)
+                    .gt(ApproveNode::getApproveNodeOrder, node.getApproveNodeOrder())
+                    .orderByAsc(ApproveNode::getApproveNodeOrder)
+                    .last("limit 1"));
+            if (next == null) {
+                process.setApproveStatus(2);
+                process.setApproveOverTime(new Date());
+                process.setApproveUserCurrentId(null);
+                process.setApproveUserCurrentName(null);
+            } else {
+                next.setIsCurrent(1);
+                next.setUpdateTime(LocalDateTime.now());
+                approveNodeMapper.updateById(next);
+                process.setApproveStatus(1);
+                process.setApproveUserCurrentId(next.getApproveNodeUserId());
+                process.setApproveUserCurrentName(next.getApproveNodeUser());
             }
-            approveNode.setIsShen(true);
-            break;
         }
-        return list;
+        process.setUpdateTime(LocalDateTime.now());
+        approveProcessMapper.updateById(process);
+
+        ApproveLog log = new ApproveLog();
+        log.setApproveId(process.getId());
+        log.setApproveProcessId(process.getId());
+        log.setApproveNodeId(node.getId());
+        log.setApproveNodeOrder(node.getApproveNodeOrder());
+        log.setApproveUser(SecurityUtils.getUserId());
+        log.setApproveUserName(node.getApproveNodeUser());
+        log.setApproveTime(new Date());
+        log.setApproveStatus(node.getApproveNodeStatus());
+        log.setApproveRemark(node.getApproveNodeReason());
+        log.setTenantId(tenantId);
+        approveLogMapper.insert(log);
+
+        if (!CollectionUtils.isEmpty(request.getTempFileIds()) && node.getApproveNodeStatus() == 1) {
+            tempFileService.migrateTempFilesToFormal(node.getId(), request.getTempFileIds(), FileNameType.ApproveNode.getValue());
+        }
     }
 
     @Override
-    public void updateApproveNode(ApproveNode approveNode) {
-        // 瀹℃壒鑺傜偣鐘舵��:1鍚屾剰锛�2鎷掔粷锛�0灏氭湭瀹℃牳
-        switch (approveNode.getApproveNodeStatus()){
-            case 1:
-                approveProcessService.updateApproveProcessStatus(approveNode, Boolean.TRUE.equals(approveNode.getIsLast()) ? 2 : 1);
-                break;
-            case 2:
-                approveProcessService.updateApproveProcessStatus(approveNode, 3);
-                break;
-            default:
-                break;
-        }
-        approveNode.setApproveNodeTime(new Date());
-        approveNodeMapper.updateById(approveNode);
+    public void delApproveNodeByApproveId(String id) {
+        UpdateWrapper<ApproveNode> wrapper = new UpdateWrapper<>();
+        wrapper.lambda().set(ApproveNode::getDeleteFlag, 1)
+                .set(ApproveNode::getIsCurrent, 0)
+                .eq(ApproveNode::getApproveProcessId, id)
+                .eq(ApproveNode::getTenantId, tenantId());
+        update(wrapper);
     }
 
-    @Override
-    public void delApproveNodeByApproveId(Long id) {
-        UpdateWrapper<ApproveNode> queryWrapper = new UpdateWrapper<>();
-        queryWrapper.lambda().set(ApproveNode::getDeleteFlag, 1)
-                .eq(ApproveNode::getApproveProcessId, id);
-        update(queryWrapper);
+    private Long tenantId() {
+        return SecurityUtils.getLoginUser().getTenantId();
     }
-
 }

--
Gitblit v1.9.3