瀏覽代碼

租户初始化

车车 4 月之前
父節點
當前提交
4281ac1d35

+ 10 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/biz/iscs/IscsInitApi.java

@@ -0,0 +1,10 @@
+package cn.iocoder.yudao.framework.common.biz.iscs;
+
+import cn.iocoder.yudao.framework.common.biz.iscs.dto.InitWorkDTO;
+
+public interface IscsInitApi {
+
+    void workInit(InitWorkDTO dto);
+
+
+}

+ 18 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/biz/iscs/dto/InitWorkDTO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.framework.common.biz.iscs.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class InitWorkDTO {
+
+    private Long tenantId;
+
+    private Long lockPerson;
+
+    private List<Long> coLockPersons;
+
+    private Long workerUserId;
+
+}

+ 451 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/api/task/IscsInitApiImpl.java

@@ -0,0 +1,451 @@
+package cn.iocoder.yudao.module.iscs.api.task;
+
+import cn.iocoder.yudao.framework.common.biz.iscs.IscsInitApi;
+import cn.iocoder.yudao.framework.common.biz.iscs.dto.InitWorkDTO;
+import cn.iocoder.yudao.module.iscs.controller.admin.workdesign.workflowdesign.vo.WorkflowDesignSaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.workdesign.workflowwork.vo.WorkflowWorkSaveReqVO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.isolationpoint.IsolationPointDO;
+import cn.iocoder.yudao.module.iscs.service.isolationpoint.IsolationPointService;
+import cn.iocoder.yudao.module.iscs.service.workdesign.WorkflowDesignService;
+import cn.iocoder.yudao.module.iscs.service.workdesign.WorkflowWorkService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+@Service
+@Validated
+public class IscsInitApiImpl implements IscsInitApi {
+
+    @Resource
+    private IsolationPointService isolationPointService;
+
+    @Resource
+    private WorkflowDesignService workflowDesignService;
+    @Resource
+    private WorkflowWorkService workflowWorkService;
+
+
+    @Override
+    public void workInit(InitWorkDTO dto) {
+        Long tenantId = dto.getTenantId();
+        Long lockPerson = dto.getLockPerson();
+        List<Long> coLockPersons = dto.getCoLockPersons();
+        Long workerUserId = dto.getWorkerUserId();
+        System.out.println("tenantId---------" + tenantId);
+
+
+        // 点位相关初始化
+        IsolationPointDO isolationPointDO1 = new IsolationPointDO();
+        isolationPointDO1.setPointName("UPS总闸");
+
+        IsolationPointDO isolationPointDO2 = new IsolationPointDO();
+        isolationPointDO2.setPointName("电机总开");
+
+        IsolationPointDO isolationPointDO3 = new IsolationPointDO();
+        isolationPointDO3.setPointName("电机总开");
+
+        List<IsolationPointDO> isolationPointDOS = new ArrayList<>();
+        isolationPointDOS.add(isolationPointDO1);
+        isolationPointDOS.add(isolationPointDO2);
+        isolationPointDOS.add(isolationPointDO3);
+        isolationPointService.saveBatch(isolationPointDOS);
+
+        List<Long> isolationPoints = new ArrayList<>();
+        isolationPoints.add(isolationPointDO1.getId());
+        isolationPoints.add(isolationPointDO2.getId());
+        isolationPoints.add(isolationPointDO3.getId());
+
+        // 流程模板初始化
+        WorkflowDesignSaveReqVO workflowDesignSaveReqVO = new WorkflowDesignSaveReqVO();
+        workflowDesignSaveReqVO.setName("作业流程实例");
+        workflowDesignSaveReqVO.setContent(getInitJson(isolationPoints, lockPerson, coLockPersons, workerUserId));
+        workflowDesignSaveReqVO.setDescription("初始化作业模板");
+        Long workflowDesign = workflowDesignService.createWorkflowDesign(workflowDesignSaveReqVO);
+
+        // 根据模板生成作业
+        WorkflowWorkSaveReqVO workflowWorkSaveReqVO = new WorkflowWorkSaveReqVO();
+        workflowWorkSaveReqVO.setName("标准维修作业" + new Random().nextInt(1000));
+        workflowWorkSaveReqVO.setType("1");
+        workflowWorkSaveReqVO.setUrgencyLevel("0");
+        workflowWorkSaveReqVO.setDesignId(workflowDesign);
+        workflowWorkService.createWorkflowWork(workflowWorkSaveReqVO);
+
+    }
+
+
+    private static String getInitJson(List<Long> isolationPoints, Long lockPerson, List<Long> coLockPersons, Long workerUserId) {
+        String originalJsonStr = "{\n" +
+                "  \"nodeCount\" : 6,\n" +
+                "  \"edgeCount\" : 5,\n" +
+                "  \"adjacency\" : {\n" +
+                "    \"createJob-1766650792290\" : {\n" +
+                "      \"parentUuid\" : [ ],\n" +
+                "      \"childrenUuid\" : [ \"review-1766650839450\" ]\n" +
+                "    },\n" +
+                "    \"confirm-1766650799337\" : {\n" +
+                "      \"parentUuid\" : [ \"review-1766650839450\" ],\n" +
+                "      \"childrenUuid\" : [ \"isolation-1766650858056\" ]\n" +
+                "    },\n" +
+                "    \"review-1766650839450\" : {\n" +
+                "      \"parentUuid\" : [ \"createJob-1766650792290\" ],\n" +
+                "      \"childrenUuid\" : [ \"confirm-1766650799337\" ]\n" +
+                "    },\n" +
+                "    \"isolation-1766650858056\" : {\n" +
+                "      \"parentUuid\" : [ \"confirm-1766650799337\" ],\n" +
+                "      \"childrenUuid\" : [ \"releaseIsolation-1766650866562\" ]\n" +
+                "    },\n" +
+                "    \"releaseIsolation-1766650866562\" : {\n" +
+                "      \"parentUuid\" : [ \"isolation-1766650858056\" ],\n" +
+                "      \"childrenUuid\" : [ \"complete-1766650878643\" ]\n" +
+                "    },\n" +
+                "    \"complete-1766650878643\" : {\n" +
+                "      \"parentUuid\" : [ \"releaseIsolation-1766650866562\" ],\n" +
+                "      \"childrenUuid\" : [ ]\n" +
+                "    }\n" +
+                "  },\n" +
+                "  \"nodes\" : [ {\n" +
+                "    \"uuid\" : \"createJob-1766650792290\",\n" +
+                "    \"type\" : \"createJob\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 22.01707056367252,\n" +
+                "      \"y\" : 50.73719707724561\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"创建作业\",\n" +
+                "    \"nodeIcon\" : \"2007.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"创建作业\",\n" +
+                "      \"type\" : \"createJob\",\n" +
+                "      \"nodeId\" : \"001\",\n" +
+                "      \"icon\" : \"2007.png\",\n" +
+                "      \"workerUserId\" : 251,\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"\",\n" +
+                "      \"isolationType\" : \"\",\n" +
+                "      \"isolationPoints\" : [ ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"\",\n" +
+                "      \"lockPerson\" : \"\",\n" +
+                "      \"coLockPersons\" : [ ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"创建作业\",\n" +
+                "      \"nodeIcon\" : \"2007.png\"\n" +
+                "    }\n" +
+                "  }, {\n" +
+                "    \"uuid\" : \"confirm-1766650799337\",\n" +
+                "    \"type\" : \"confirm\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 351.78708474285037,\n" +
+                "      \"y\" : 24.381477335664925\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"现场勘察确认\",\n" +
+                "    \"nodeIcon\" : \"4005.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"现场勘察确认\",\n" +
+                "      \"type\" : \"confirm\",\n" +
+                "      \"nodeId\" : \"002\",\n" +
+                "      \"icon\" : \"4005.png\",\n" +
+                "      \"workerUserId\" : 251,\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"53\",\n" +
+                "      \"isolationType\" : \"\",\n" +
+                "      \"isolationPoints\" : [ ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"\",\n" +
+                "      \"lockPerson\" : \"\",\n" +
+                "      \"coLockPersons\" : [ ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"现场勘察确认\",\n" +
+                "      \"nodeIcon\" : \"4005.png\"\n" +
+                "    }\n" +
+                "  }, {\n" +
+                "    \"uuid\" : \"review-1766650839450\",\n" +
+                "    \"type\" : \"review\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 189.9974210811705,\n" +
+                "      \"y\" : 50.68595889912385\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"作业审核\",\n" +
+                "    \"nodeIcon\" : \"1004.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"作业审核\",\n" +
+                "      \"type\" : \"review\",\n" +
+                "      \"nodeId\" : \"003\",\n" +
+                "      \"icon\" : \"1004.png\",\n" +
+                "      \"workerUserId\" : 251,\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"54\",\n" +
+                "      \"isolationType\" : \"\",\n" +
+                "      \"isolationPoints\" : [ ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"\",\n" +
+                "      \"lockPerson\" : \"\",\n" +
+                "      \"coLockPersons\" : [ ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"作业审核\",\n" +
+                "      \"nodeIcon\" : \"1004.png\"\n" +
+                "    }\n" +
+                "  }, {\n" +
+                "    \"uuid\" : \"isolation-1766650858056\",\n" +
+                "    \"type\" : \"isolation\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 562.101351432562,\n" +
+                "      \"y\" : 51.367615523177534\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"能量隔离\",\n" +
+                "    \"nodeIcon\" : \"6005.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"能量隔离\",\n" +
+                "      \"type\" : \"isolation\",\n" +
+                "      \"nodeId\" : \"005\",\n" +
+                "      \"icon\" : \"6005.png\",\n" +
+                "      \"workerUserId\" : \"\",\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"55\",\n" +
+                "      \"isolationType\" : \"1\",\n" +
+                "      \"isolationPoints\" : [ 130, 130, 130 ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"\",\n" +
+                "      \"lockPerson\" : 249,\n" +
+                "      \"coLockPersons\" : [ 250 ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"能量隔离\",\n" +
+                "      \"nodeIcon\" : \"6005.png\"\n" +
+                "    }\n" +
+                "  }, {\n" +
+                "    \"uuid\" : \"releaseIsolation-1766650866562\",\n" +
+                "    \"type\" : \"releaseIsolation\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 764.9565268541271,\n" +
+                "      \"y\" : 50.876612170258824\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"解除隔离\",\n" +
+                "    \"nodeIcon\" : \"7007.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"解除隔离\",\n" +
+                "      \"type\" : \"releaseIsolation\",\n" +
+                "      \"nodeId\" : \"006\",\n" +
+                "      \"icon\" : \"7007.png\",\n" +
+                "      \"workerUserId\" : \"\",\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"54\",\n" +
+                "      \"isolationType\" : \"1\",\n" +
+                "      \"isolationPoints\" : [ 130, 130, 130 ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"isolation-1766650858056\",\n" +
+                "      \"lockPerson\" : 249,\n" +
+                "      \"coLockPersons\" : [ 250 ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"isolation-1766650858056\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"解除隔离\",\n" +
+                "      \"nodeIcon\" : \"7007.png\"\n" +
+                "    }\n" +
+                "  }, {\n" +
+                "    \"uuid\" : \"complete-1766650878643\",\n" +
+                "    \"type\" : \"complete\",\n" +
+                "    \"position\" : {\n" +
+                "      \"x\" : 961.8893632852687,\n" +
+                "      \"y\" : 50.305803156917875\n" +
+                "    },\n" +
+                "    \"nodeName\" : \"完成/结束\",\n" +
+                "    \"nodeIcon\" : \"5006.png\",\n" +
+                "    \"smsTemplateCode\" : \"false\",\n" +
+                "    \"messageTemplateCode\" : \"false\",\n" +
+                "    \"emailTemplateCode\" : \"false\",\n" +
+                "    \"appTemplateCode\" : \"false\",\n" +
+                "    \"data\" : {\n" +
+                "      \"label\" : \"完成/结束\",\n" +
+                "      \"type\" : \"complete\",\n" +
+                "      \"nodeId\" : \"008\",\n" +
+                "      \"icon\" : \"5006.png\",\n" +
+                "      \"workerUserId\" : 251,\n" +
+                "      \"remark\" : \"\",\n" +
+                "      \"formId\" : \"58\",\n" +
+                "      \"isolationType\" : \"\",\n" +
+                "      \"isolationPoints\" : [ ],\n" +
+                "      \"isolationNode\" : [ ],\n" +
+                "      \"isolationNodeUuid\" : \"\",\n" +
+                "      \"lockPerson\" : \"\",\n" +
+                "      \"coLockPersons\" : [ ],\n" +
+                "      \"notificationMethods\" : {\n" +
+                "        \"sms\" : false,\n" +
+                "        \"message\" : false,\n" +
+                "        \"email\" : false,\n" +
+                "        \"app\" : false\n" +
+                "      },\n" +
+                "      \"notificationPerson\" : \"\",\n" +
+                "      \"notificationTime\" : \"\",\n" +
+                "      \"selectedIsolationNodeId\" : \"\",\n" +
+                "      \"submitForm\" : \"\",\n" +
+                "      \"nodeName\" : \"完成/结束\",\n" +
+                "      \"nodeIcon\" : \"5006.png\"\n" +
+                "    }\n" +
+                "  } ],\n" +
+                "  \"edges\" : [ {\n" +
+                "    \"id\" : \"edge-releaseIsolation-1766650866562-left-source-isolation-1766650858056-right-target-1766650870118\",\n" +
+                "    \"source\" : \"releaseIsolation-1766650866562\",\n" +
+                "    \"target\" : \"isolation-1766650858056\",\n" +
+                "    \"sourceHandle\" : \"left-source\",\n" +
+                "    \"targetHandle\" : \"right-target\",\n" +
+                "    \"type\" : \"straight\"\n" +
+                "  }, {\n" +
+                "    \"id\" : \"edge-confirm-1766650799337-left-source-createJob-1766650792290-right-target-1766657015939\",\n" +
+                "    \"source\" : \"review-1766650839450\",\n" +
+                "    \"target\" : \"createJob-1766650792290\",\n" +
+                "    \"sourceHandle\" : \"left-source\",\n" +
+                "    \"targetHandle\" : \"right-target\",\n" +
+                "    \"type\" : \"straight\"\n" +
+                "  }, {\n" +
+                "    \"id\" : \"edge-confirm-1766650799337-left-source-review-1766650839450-right-target-1767073828489\",\n" +
+                "    \"source\" : \"confirm-1766650799337\",\n" +
+                "    \"target\" : \"review-1766650839450\",\n" +
+                "    \"sourceHandle\" : \"left-source\",\n" +
+                "    \"targetHandle\" : \"right-target\",\n" +
+                "    \"type\" : \"straight\"\n" +
+                "  }, {\n" +
+                "    \"id\" : \"edge-isolation-1766650858056-left-source-confirm-1766650799337-right-target-1767073842505\",\n" +
+                "    \"source\" : \"isolation-1766650858056\",\n" +
+                "    \"target\" : \"confirm-1766650799337\",\n" +
+                "    \"sourceHandle\" : \"left-source\",\n" +
+                "    \"targetHandle\" : \"right-target\",\n" +
+                "    \"type\" : \"straight\"\n" +
+                "  }, {\n" +
+                "    \"id\" : \"edge-complete-1766650878643-left-source-releaseIsolation-1766650866562-right-target-1767074071353\",\n" +
+                "    \"source\" : \"complete-1766650878643\",\n" +
+                "    \"target\" : \"releaseIsolation-1766650866562\",\n" +
+                "    \"sourceHandle\" : \"left-source\",\n" +
+                "    \"targetHandle\" : \"right-target\",\n" +
+                "    \"type\" : \"straight\"\n" +
+                "  } ]\n" +
+                "}";
+
+        // 初始化ObjectMapper(建议声明为类的成员变量,避免重复创建)
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        try {
+            // 1. 将原始JSON字符串解析为可修改的ObjectNode
+            ObjectNode rootNode = (ObjectNode) objectMapper.readTree(originalJsonStr);
+
+            // 2. 获取nodes数组节点
+            ArrayNode nodesArray = (ArrayNode) rootNode.get("nodes");
+
+            // 3. 遍历nodes数组,找到type为isolation和releaseIsolation的节点并替换字段
+            for (JsonNode node : nodesArray) {
+                if (node instanceof ObjectNode nodeObj) {
+                    String nodeType = nodeObj.get("type").asText();
+
+                    // 只处理能量隔离和解除隔离节点
+                    if ("isolation".equals(nodeType) || "releaseIsolation".equals(nodeType)) {
+                        ObjectNode dataNode = (ObjectNode) nodeObj.get("data");
+
+                        // 替换isolationPoints(隔离点列表)
+                        ArrayNode isolationPointsArray = objectMapper.valueToTree(isolationPoints);
+                        dataNode.set("isolationPoints", isolationPointsArray);
+
+                        // 替换lockPerson(锁具负责人),处理null情况
+                        if (lockPerson != null) {
+                            dataNode.put("lockPerson", lockPerson);
+                        } else {
+                            dataNode.putNull("lockPerson"); // 若为null则设为JSON null
+                        }
+
+                        // 替换coLockPersons(协同锁具人员列表)
+                        ArrayNode coLockPersonsArray = objectMapper.valueToTree(coLockPersons);
+                        dataNode.set("coLockPersons", coLockPersonsArray);
+                    } else {
+                        ObjectNode dataNode = (ObjectNode) nodeObj.get("data");
+                        // 替换节点负责人,处理null情况
+                        if (workerUserId != null) {
+                            dataNode.put("workerUserId", workerUserId);
+                        } else {
+                            dataNode.putNull("workerUserId"); // 若为null则设为JSON null
+                        }
+                    }
+                }
+            }
+
+            // 4. 将修改后的JSON节点转回格式化的字符串(保持可读性)
+            return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
+
+        } catch (JsonProcessingException e) {
+            // 异常处理:打印日志并返回原始字符串(或根据业务需求调整)
+            e.printStackTrace();
+            return originalJsonStr; // 解析失败时返回原始字符串,避免返回null
+        }
+
+    }
+
+
+}

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/workdesign/workflowworknodeuser/vo/WorkflowWorkNodeUserRespVO.java

@@ -52,4 +52,8 @@ public class WorkflowWorkNodeUserRespVO {
     @ExcelProperty("avatar")
     private String avatar;
 
+    @Schema(description = "cardNfc")
+    @ExcelProperty("cardNfc")
+    private String cardNfc;
+
 }

+ 2 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/workdesign/WorkflowWorkServiceImpl.java

@@ -305,8 +305,10 @@ public class WorkflowWorkServiceImpl extends ServiceImpl<WorkflowWorkMapper, Wor
                     workflowWorkNodeUserRespVO.setNickname(adminUserDO.getNickname());
                     workflowWorkNodeUserRespVO.setMobile(adminUserDO.getMobile());
                     workflowWorkNodeUserRespVO.setAvatar(adminUserDO.getAvatar());
+                    workflowWorkNodeUserRespVO.setCardNfc(adminUserDO.getCardNfc());
                 }
             }
+            bean.setNodeUserList(nodeUserRespVOList);
         }
         return bean;
     }

+ 22 - 0
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleMenusVO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role;
+
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - 角色菜单信息")
+@Data
+@ExcelIgnoreUnannotated
+public class RoleMenusVO {
+
+    @Schema(description = "角色List")
+    private List<RoleDO> roleDOList;
+
+    @Schema(description = "角色菜单List")
+    private List<RoleMenuDO> roleMenuDOList;
+
+}

+ 3 - 0
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java

@@ -60,6 +60,9 @@ public class TenantSaveReqVO {
     @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
     private String password;
 
+    @Schema(description = "部门")
+    private Long deptId;
+
     @AssertTrue(message = "用户账号、密码不能为空")
     @JsonIgnore
     public boolean isUsernameValid() {

+ 1 - 1
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java

@@ -19,7 +19,7 @@ public interface TenantConvert {
         UserSaveReqVO reqVO = new UserSaveReqVO();
         reqVO.setUsername(bean.getUsername());
         reqVO.setPassword(bean.getPassword());
-        reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
+        reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile()).setDeptId(bean.getDeptId());
         return reqVO;
     }
 

+ 155 - 18
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java

@@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.biz.iscs.IscsInitApi;
+import cn.iocoder.yudao.framework.common.biz.iscs.dto.InitWorkDTO;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -14,6 +16,7 @@ import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleMenusVO;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
@@ -22,8 +25,10 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
+import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
 import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
@@ -45,10 +50,7 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -84,11 +86,15 @@ public class TenantServiceImpl implements TenantService {
     @Resource
     private DeptService deptService;
     @Resource
+    private RoleMenuMapper roleMenuMapper;
+    @Resource
     private DictTypeService dictTypeService;
     @Resource
     private DictDataService dictDataService;
     @Resource
     private PermissionService permissionService;
+    @Resource
+    private IscsInitApi iscsInitApi;
 
     @Override
     public List<Long> getTenantIdList() {
@@ -132,25 +138,36 @@ public class TenantServiceImpl implements TenantService {
         // 获取字典,给新租户配置一套
         List<DictTypeDO> dictTypeList = dictTypeService.getDictTypeList();
         List<DictDataDO> dictDataList = dictDataService.getDictDataList(null, null);
+        // 获取旧的角色和角色菜单
+        RoleMenusVO oldRoleList = getOldRoleList();
         // 创建租户的管理员
         TenantUtils.execute(tenant.getId(), () -> {
             // 创建菜单
-            Set<Long> longs = createMenu(menuDOS, tenant.getId());
+            List<MenuDO> menu = createMenu(menuDOS, tenant.getId());
+            Set<Long> longs = menu.stream().map(MenuDO::getId).collect(Collectors.toSet());
             tenantPackage.setMenuIds(longs);
             // 创建字典
             createDict(dictTypeList, dictDataList);
-            // 创建角色
+            // 创建租户管理员角色
             Long roleId = createRole(tenantPackage);
+            // 创建init角色
+            List<RoleDO> initRoles = createInitRoles(tenant.getId(), oldRoleList, menu);
+            // 创建部门
+            Long deptId = createDept(createReqVO);
             // 创建用户,并分配角色
             Long userId = createUser(roleId, createReqVO);
-            // 创建部门
-            createDept(createReqVO);
+            // 创建init用户,并分配角色
+            InitWorkDTO initUsers = createInitUsers(deptId, tenant.getId(), initRoles);
             // 修改租户的管理员
             tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId));
+            // 创建init作业
+            iscsInitApi.workInit(initUsers);
         });
         return tenant.getId();
     }
 
+
+
     private void createDict(List<DictTypeDO> dictTypeList, List<DictDataDO> dictDataList) {
         dictTypeList.forEach(o -> o.setId(null).setTenantId(null));
         dictTypeService.saveBatch(dictTypeList);
@@ -166,7 +183,72 @@ public class TenantServiceImpl implements TenantService {
         return userId;
     }
 
-    private void createDept(TenantSaveReqVO createReqVO) {
+    private InitWorkDTO createInitUsers(Long deptId, Long tenantId, List<RoleDO> initRoles) {
+        // 初始化需要新增的人员信息
+        // 普通管理员
+        TenantSaveReqVO tenantSaveReqVO1 = new TenantSaveReqVO();
+        tenantSaveReqVO1.setName("张三");
+        tenantSaveReqVO1.setContactName("张三");
+        tenantSaveReqVO1.setUsername("zhangsan");
+        tenantSaveReqVO1.setPassword("123890hzb");
+        tenantSaveReqVO1.setDeptId(deptId);
+        Optional<RoleDO> roleDO1 = initRoles.stream().filter(o -> o.getCode().equals("enSuperadmin")).findFirst();
+        Long user1 = createUser(roleDO1.get().getId(), tenantSaveReqVO1);
+
+        // 上锁人
+        TenantSaveReqVO tenantSaveReqVO2 = new TenantSaveReqVO();
+        tenantSaveReqVO2.setName("李四");
+        tenantSaveReqVO2.setContactName("李四");
+        tenantSaveReqVO2.setUsername("lisi");
+        tenantSaveReqVO2.setPassword("123890hzb");
+        tenantSaveReqVO2.setDeptId(deptId);
+        Optional<RoleDO> roleDO2 = initRoles.stream().filter(o -> o.getCode().equals("jtlocker")).findFirst();
+        Long lockPerson = createUser(roleDO2.get().getId(), tenantSaveReqVO2);
+
+        // 共锁人
+        TenantSaveReqVO tenantSaveReqVO3 = new TenantSaveReqVO();
+        tenantSaveReqVO3.setName("王五");
+        tenantSaveReqVO3.setContactName("王五");
+        tenantSaveReqVO3.setUsername("wangwu");
+        tenantSaveReqVO3.setPassword("123890hzb");
+        tenantSaveReqVO3.setDeptId(deptId);
+        Optional<RoleDO> roleDO3 = initRoles.stream().filter(o -> o.getCode().equals("jtcolocker")).findFirst();
+        Long user3 = createUser(roleDO3.get().getId(), tenantSaveReqVO3);
+
+        // 作业参与人
+        TenantSaveReqVO tenantSaveReqVO4 = new TenantSaveReqVO();
+        tenantSaveReqVO4.setName("温博一");
+        tenantSaveReqVO4.setContactName("温博一");
+        tenantSaveReqVO4.setUsername("wbyy");
+        tenantSaveReqVO4.setPassword("123890hzb");
+        tenantSaveReqVO4.setDeptId(deptId);
+        Optional<RoleDO> roleDO4 = initRoles.stream().filter(o -> o.getCode().equals("jtcolocker")).findFirst();
+        Long workerUserId = createUser(roleDO4.get().getId(), tenantSaveReqVO4);
+
+        // 作业参与人
+        TenantSaveReqVO tenantSaveReqVO5 = new TenantSaveReqVO();
+        tenantSaveReqVO5.setName("温博二");
+        tenantSaveReqVO5.setContactName("温博二");
+        tenantSaveReqVO5.setUsername("wbee");
+        tenantSaveReqVO5.setPassword("123890hzb");
+        tenantSaveReqVO5.setDeptId(deptId);
+        Optional<RoleDO> roleDO5 = initRoles.stream().filter(o -> o.getCode().equals("jtcolocker")).findFirst();
+        createUser(roleDO5.get().getId(), tenantSaveReqVO5);
+
+        // 整合人员数据
+        InitWorkDTO initWorkDTO = new InitWorkDTO();
+        initWorkDTO.setTenantId(tenantId);
+        initWorkDTO.setLockPerson(lockPerson);
+        ArrayList<Long> coLockPersons = new ArrayList<>();
+        coLockPersons.add(user3);
+        initWorkDTO.setCoLockPersons(coLockPersons);
+        initWorkDTO.setWorkerUserId(workerUserId);
+        return initWorkDTO;
+    }
+
+
+
+    private Long createDept(TenantSaveReqVO createReqVO) {
         // 顶级
         DeptSaveReqVO deptSaveReqVO = new DeptSaveReqVO();
         deptSaveReqVO.setName(createReqVO.getName());
@@ -176,17 +258,17 @@ public class TenantServiceImpl implements TenantService {
         deptSaveReqVO.setCode("top");
         Long topDeptId = deptService.createDept(deptSaveReqVO);
 
-        // 虚拟
-       /* DeptSaveReqVO deptSaveReqVO1 = new DeptSaveReqVO();
-        deptSaveReqVO1.setName("作业(虚拟)分组");
+        // IT部门
+        DeptSaveReqVO deptSaveReqVO1 = new DeptSaveReqVO();
+        deptSaveReqVO1.setName("科技部门");
         deptSaveReqVO1.setParentId(topDeptId);
         deptSaveReqVO1.setSort(1);
         deptSaveReqVO1.setStatus(0);
-        deptSaveReqVO1.setCode("jtdept");
+        deptSaveReqVO1.setCode("it-dept");
         Long deptId1 = deptService.createDept(deptSaveReqVO1);
 
         // 上锁
-        DeptSaveReqVO deptSaveReqVO2 = new DeptSaveReqVO();
+        /*DeptSaveReqVO deptSaveReqVO2 = new DeptSaveReqVO();
         deptSaveReqVO2.setName("上锁");
         deptSaveReqVO2.setParentId(deptId1);
         deptSaveReqVO2.setSort(1);
@@ -211,6 +293,7 @@ public class TenantServiceImpl implements TenantService {
         deptSaveReqVO4.setStatus(0);
         deptSaveReqVO4.setCode("jtdrawer");
         deptService.createDept(deptSaveReqVO4);*/
+        return deptId1;
     }
 
     private Long createRole(TenantPackageDO tenantPackage) {
@@ -224,7 +307,60 @@ public class TenantServiceImpl implements TenantService {
         return roleId;
     }
 
-    private Set<Long> createMenu(List<MenuDO> menuDOS, Long tenantId) {
+    private RoleMenusVO getOldRoleList() {
+        List<String> initRoleCodeList = new ArrayList<>();
+        initRoleCodeList.add("enSuperadmin");
+        initRoleCodeList.add("common");
+        initRoleCodeList.add("jtlocker");
+        initRoleCodeList.add("jtcolocker");
+        initRoleCodeList.add("jtdrawer");
+        // 查询原来的角色
+        List<RoleDO> oldRoleList = roleService.list(Wrappers.<RoleDO>lambdaQuery().in(RoleDO::getCode, initRoleCodeList));
+        System.out.println("oldRoleList---" + oldRoleList);
+        // 查询原来角色的菜单
+        List<Long> oldRoleIds = oldRoleList.stream().map(RoleDO::getId).toList();
+        List<RoleMenuDO> roleMenuDOS = roleMenuMapper.selectList(Wrappers.<RoleMenuDO>lambdaQuery().in(RoleMenuDO::getRoleId, oldRoleIds));
+        RoleMenusVO roleMenusVO = new RoleMenusVO();
+        roleMenusVO.setRoleDOList(oldRoleList);
+        roleMenusVO.setRoleMenuDOList(roleMenuDOS);
+        return roleMenusVO;
+    }
+
+    private List<RoleDO> createInitRoles(Long tenantId, RoleMenusVO oldRoleMenu, List<MenuDO> menu) {
+        List<RoleDO> oldRoleDOList = oldRoleMenu.getRoleDOList();
+        List<RoleMenuDO> oldRoleMenuDOList = oldRoleMenu.getRoleMenuDOList();
+        List<RoleDO> newRoleList = new ArrayList<>();
+        // 开始新增
+        for (RoleDO oldRoleDO : oldRoleDOList) {
+            RoleDO newRole = BeanUtils.toBean(oldRoleDO, RoleDO.class);
+            newRole.setId(null);
+            newRole.setTenantId(tenantId);
+            roleService.save(newRole);
+            newRoleList.add(newRole);
+            // 查找老role对应的菜单
+            List<Long> oldMenuIdList = oldRoleMenuDOList.stream().filter(o -> o.getRoleId().equals(oldRoleDO.getId())).map(RoleMenuDO::getMenuId).toList();
+            Set<Long> oldMenuIdSet = new HashSet<>(oldMenuIdList);
+            if (!oldMenuIdList.isEmpty()) {
+                // 获取老role对应的新的菜单(为什么要查一遍,因为套餐里面可能有些菜单是没有给的,新的菜单已经生成,查一遍可以只找套餐里有的菜单)
+                List<MenuDO> newMenuList = menu.stream()
+                        .filter(menuDO -> oldMenuIdSet.contains(menuDO.getOldId()))
+                        .toList();
+                // 开始给新的角色加上这些菜单
+                List<RoleMenuDO> roleMenuDOS = new ArrayList<>();
+                for (MenuDO menuDO : newMenuList) {
+                    RoleMenuDO roleMenuDO = new RoleMenuDO();
+                    roleMenuDO.setRoleId(newRole.getId());
+                    roleMenuDO.setMenuId(menuDO.getId());
+                    roleMenuDO.setTenantId(tenantId);
+                    roleMenuDOS.add(roleMenuDO);
+                }
+                roleMenuMapper.insertBatch(roleMenuDOS);
+            }
+        }
+        return newRoleList;
+    }
+
+    private List<MenuDO> createMenu(List<MenuDO> menuDOS, Long tenantId) {
         menuDOS.forEach(o -> o.setTenantId(tenantId));
         menuService.saveBatch(menuDOS);
         for (MenuDO menuDO : menuDOS) {
@@ -235,8 +371,8 @@ public class TenantServiceImpl implements TenantService {
         }
         menuService.updateBatchById(menuDOS);
         // 替换返回值
-        Set<Long> longs = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toSet());
-        return longs;
+        // Set<Long> longs = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toSet());
+        return menuDOS;
     }
 
     @Override
@@ -304,7 +440,8 @@ public class TenantServiceImpl implements TenantService {
             // 先删除现在的菜单
             menuService.remove(Wrappers.<MenuDO>lambdaQuery().eq(MenuDO::getTenantId, tenantId));
             // 创建菜单
-            Set<Long> longs = createMenu(menuDOS, tenantId);
+            List<MenuDO> menu = createMenu(menuDOS, tenantId);
+            Set<Long> longs = menu.stream().map(MenuDO::getId).collect(Collectors.toSet());
             // 获得所有角色
             List<RoleDO> roles = roleService.getRoleList();
             roles.forEach(role -> Assert.isTrue(tenantId.equals(role.getTenantId()), "角色({}/{}) 租户不匹配",