diff --git a/common/src/main/java/com/sdm/common/entity/req/lyric/SpdmAcceptTodoInfoReq.java b/common/src/main/java/com/sdm/common/entity/req/lyric/SpdmAcceptTodoInfoReq.java new file mode 100644 index 00000000..4893f47c --- /dev/null +++ b/common/src/main/java/com/sdm/common/entity/req/lyric/SpdmAcceptTodoInfoReq.java @@ -0,0 +1,29 @@ +package com.sdm.common.entity.req.lyric; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class SpdmAcceptTodoInfoReq { + + /** + * 项目号 + */ + private String projectNum; + + /** + * 机台 + */ + private String machineNum; + + /** + * 工位号 + */ + private String stationNum; + + /** + * 物料号 + */ + private String materialNo; + +} diff --git a/common/src/main/java/com/sdm/common/entity/resp/system/SysDeptUserResp.java b/common/src/main/java/com/sdm/common/entity/resp/system/SysDeptUserResp.java new file mode 100644 index 00000000..12d21722 --- /dev/null +++ b/common/src/main/java/com/sdm/common/entity/resp/system/SysDeptUserResp.java @@ -0,0 +1,39 @@ +package com.sdm.common.entity.resp.system; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class SysDeptUserResp { + + @Schema(description = "主键ID") + private Integer id; + + @Schema(description = "部门ID") + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long deptId; + + @Schema(description = "部门名称") + private String deptName; + + @Schema(description = "部门负责人用户ID") + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long userId; + private CIDUserResp userResp; + + @Schema(description = "所属租户ID") + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long tenantId; + + @Schema(description = "创建人") + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long creator; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + +} diff --git a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java index 361da08b..7dbe9db2 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java @@ -1,6 +1,7 @@ package com.sdm.project.controller; import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.req.lyric.SpdmAcceptTodoInfoReq; import com.sdm.common.entity.req.project.SpdmNodeListReq; import com.sdm.common.entity.resp.PageDataResp; import com.sdm.outbridge.entity.LyricVProjectStationExcepTionToDM; @@ -214,5 +215,15 @@ public class SimulationLyricNodeController { return lyricInternalService.queryEncExceptionByTaskId(taskId,current,size); } + /** + * 从MES接收项目号、机台、工位号、物料号。根据接收到的信息创建待办 + * + */ + @GetMapping("/acceptTodoInfo") + @Operation(summary = "从MES接收项目号、机台、工位号、物料号。根据接收到的信息创建待办", description = "从MES接收项目号、机台、工位号、物料号。根据接收到的信息创建待办") + public SdmResponse acceptTodoInfo(SpdmAcceptTodoInfoReq req) { + return lyricInternalService.acceptTodoInfo(req); + } + } diff --git a/project/src/main/java/com/sdm/project/service/ILyricInternalService.java b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java index 27ba8d4f..fd6ad7f9 100644 --- a/project/src/main/java/com/sdm/project/service/ILyricInternalService.java +++ b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java @@ -1,6 +1,7 @@ package com.sdm.project.service; import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.req.lyric.SpdmAcceptTodoInfoReq; import com.sdm.common.entity.req.project.SpdmNodeListReq; import com.sdm.common.entity.resp.PageDataResp; import com.sdm.outbridge.entity.LyricVProjectStationExcepTionToDM; @@ -60,4 +61,6 @@ public interface ILyricInternalService { SdmResponse>> queryEncExceptionByTaskId(String taskId, Integer current, Integer size); + SdmResponse acceptTodoInfo(SpdmAcceptTodoInfoReq req); + } diff --git a/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java index e65966b9..b47781f8 100644 --- a/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java @@ -3,6 +3,7 @@ package com.sdm.project.service.impl; import com.alibaba.fastjson2.JSONObject; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import com.sdm.common.common.ResultCode; import com.sdm.common.common.SdmResponse; import com.sdm.common.common.ThreadLocalContext; import com.sdm.common.entity.enums.AttachFileTypeEnum; @@ -10,6 +11,7 @@ import com.sdm.common.entity.enums.DirTypeEnum; import com.sdm.common.entity.enums.FilePermissionEnum; import com.sdm.common.entity.enums.NodeTypeEnum; import com.sdm.common.entity.req.data.*; +import com.sdm.common.entity.req.lyric.SpdmAcceptTodoInfoReq; import com.sdm.common.entity.req.project.SpdmNodeListReq; import com.sdm.common.entity.req.system.UserListReq; import com.sdm.common.entity.req.system.UserQueryReq; @@ -17,6 +19,7 @@ import com.sdm.common.entity.resp.PageDataResp; import com.sdm.common.entity.resp.data.BatchCreateNormalDirResp; import com.sdm.common.entity.resp.data.FileMetadataInfoResp; import com.sdm.common.entity.resp.system.CIDUserResp; +import com.sdm.common.entity.resp.system.SysDeptUserResp; import com.sdm.common.feign.impl.data.DataClientFeignClientImpl; import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; import com.sdm.common.log.CoreLogger; @@ -63,6 +66,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; import java.io.*; @@ -213,6 +217,11 @@ public class LyricInternalServiceImpl implements ILyricInternalService { @Value("${lyricFlag:1}") private int lyricFlag; + // 用于判断查询事业部用户信息的一些常量 + private static final String DESIGN_PHASE = "设计"; + private static final String STRUCTURE = "结构"; + private static final String TECHNOLOGY_CENTER = "技术中心"; + /** * 判断字符串是否可以安全转换为Long类型 * @@ -567,9 +576,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } req.setMachineId(machineNode.getUuid()); } - }else { + } else { // 阶段不存在,同步阶段机台工位 - syncTodoPhase(todo.getCreateTime(),req.getTenantId(),todo.getProjectStage(),projectNode.getUuid(),req); + syncTodoPhase(todo.getCreateTime(), Long.valueOf(projectNode.getProjectId()), todo.getProjectStage(), projectNode.getUuid(), req); } } @@ -1681,7 +1690,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { * @param parentUuid 父节点uuid * @param dirName 待长江文件夹名称 */ - private SdmResponse createDir(String uuid, String uuidOwnType, String parentUuid, String dirName,SpdmProjectNodeEditReq spdmProjectNodeEditReq) { + private SdmResponse createDir(String uuid, String uuidOwnType, String parentUuid, String dirName, SpdmProjectNodeEditReq spdmProjectNodeEditReq) { CreateDirReq createDirReq = new CreateDirReq(); createDirReq.setUuId(uuid); createDirReq.setUuIdOwnType(uuidOwnType); @@ -1689,7 +1698,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { createDirReq.setDirName(dirName); createDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue()); TagReq tagReq = new TagReq(); - BeanUtils.copyProperties(spdmProjectNodeEditReq,tagReq); + BeanUtils.copyProperties(spdmProjectNodeEditReq, tagReq); createDirReq.setTagReq(tagReq); log.info("同步项目阶段时,调用创建文件夹的参数为:{}", createDirReq); SdmResponse response = dataFeignClient.createDir(createDirReq); @@ -1846,7 +1855,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { return null; } for (SpdmProjectNodeEditReq node : addNodeList) { - createDir(node.getUuid(), node.getNodeType(), node.getPid(), node.getNodeName(),node); + createDir(node.getUuid(), node.getNodeType(), node.getPid(), node.getNodeName(), node); } // 更新文件权限 Long userId = ThreadLocalContext.getUserId(); @@ -2179,6 +2188,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 设置项目当前阶段信息 + * * @param nodeList */ public void setCurrentPhase(List nodeList) { @@ -2199,6 +2209,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 设置EP类型项目当前阶段信息 + * * @param dmProjectNodeList */ private void setEpCurrentPhase(List dmProjectNodeList) { @@ -2243,6 +2254,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 设置自建项目当前阶段信息 + * * @param nodeList */ private void setDmCurrentPhase(List nodeList) { @@ -2295,8 +2307,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 工具方法:将时间字符串解析为时间戳,解析失败抛运行时异常 + * * @param timeStr 时间字符串(yyyy-MM-dd HH:mm:ss) - * @param sdf 时间格式化器 + * @param sdf 时间格式化器 * @return 时间戳 */ private long parseTimeToMillis(String timeStr, SimpleDateFormat sdf) { @@ -2309,9 +2322,10 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 工具方法:判断当前时间是否落在阶段节点的[开始时间, 结束时间]范围内 - * @param phaseNode 阶段节点 + * + * @param phaseNode 阶段节点 * @param currentTime 当前时间戳 - * @param sdf 时间格式化器 + * @param sdf 时间格式化器 * @return true-在范围内,false-不在/解析失败 */ private boolean isCurrentTimeInRange(SimulationNode phaseNode, long currentTime, SimpleDateFormat sdf) { @@ -2607,7 +2621,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } SpdmProjectNodeEditReq firstPhaseNode = phaseNodes.get(0); createDir(firstPhaseNode.getUuid(), firstPhaseNode.getNodeType(), - firstPhaseNode.getPid(), firstPhaseNode.getNodeName(),firstPhaseNode); + firstPhaseNode.getPid(), firstPhaseNode.getNodeName(), firstPhaseNode); } /** @@ -3373,7 +3387,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { return resultList; } - private void syncTodoPhase(String curDateStr, Long projectId, String currentPhase, String projectNodeId,SpdmAddDemandReq req) { + private void syncTodoPhase(String curDateStr, Long projectId, String currentPhase, String projectNodeId, SpdmAddDemandReq req) { Long tenantId = req.getTenantId(); Long jobNumber = req.getCreator(); List currentNodeList; @@ -3403,6 +3417,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { phaseNode.setProjectSource(SYNC_PROJECT_SOURCE); phaseNode.setPid(projectNodeId); addNodeList.add(phaseNode); + req.setPhaseId(phaseNode.getUuid()); // 机台、工位 Map> machineMap = projectStationList.stream().collect(Collectors.groupingBy(LyricVProjectStationToDM::getMachineNumber)); for (Map.Entry> machineEntry : machineMap.entrySet()) { @@ -3521,7 +3536,172 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } if (nodeMapper.addNodeBatch(addNodeList) <= 0) { - return ; + return; + } + + // 批量创建文件夹 + batchCreateNodeDir(addNodeList); + + + } + + private void syncTodoPhaseForMes(String curDateStr, Long projectId, String currentPhase, String projectNodeId, SpdmAddDemandReq req, String machineNum, String stationNum) { + Long tenantId = req.getTenantId(); + Long jobNumber = req.getCreator(); + List currentNodeList; + List addNodeList = new ArrayList<>(); + // 构建阶段——机台——工位节点树 + // 根据projectId查询项目机台工位信息的视图 + List projectStationList = new ArrayList<>(); + try { + projectStationList = lyricVProjectStationToDmService.lambdaQuery() + .eq(LyricVProjectStationToDM::getProjectId, projectId) + .list(); + } catch (MyBatisSystemException ex) { + // 查询发生异常,记录异常日志(可能是测试环境预期异常) + log.warn("查询项目机台工位信息的视图时发生异常(可能是测试环境预期异常),项目id:{},异常信息:{}", + projectId, ex.getMessage()); + } + if (CollectionUtils.isNotEmpty(projectStationList)) { + // 同步EP中的节点、机台、工位到DM + SpdmProjectNodeEditReq phaseNode = new SpdmProjectNodeEditReq(); + phaseNode.setUuid(RandomUtil.generateString(32)); + phaseNode.setNodeCode(currentPhase); + phaseNode.setNodeName(currentPhase); + phaseNode.setNodeType(NodeTypeEnum.PHASE.getValue()); + phaseNode.setCreateTime(curDateStr); + phaseNode.setCreator(jobNumber); + phaseNode.setTenantId(tenantId); + phaseNode.setProjectSource(SYNC_PROJECT_SOURCE); + phaseNode.setPid(projectNodeId); + addNodeList.add(phaseNode); + req.setProjectId(projectNodeId); + req.setPhaseId(phaseNode.getUuid()); + // 机台、工位 + Map> machineMap = projectStationList.stream().collect(Collectors.groupingBy(LyricVProjectStationToDM::getMachineNumber)); + for (Map.Entry> machineEntry : machineMap.entrySet()) { + String machineNumber = machineEntry.getKey(); + List projectStationByMachineNumberList = machineEntry.getValue(); + SpdmProjectNodeEditReq machineNode = new SpdmProjectNodeEditReq(); + machineNode.setUuid(RandomUtil.generateString(32)); + machineNode.setNodeCode(machineNumber); + machineNode.setNodeName(projectStationByMachineNumberList.get(0).getMachineName()); + machineNode.setNodeType(NodeTypeEnum.MACHINE.getValue()); + machineNode.setCreateTime(curDateStr); + machineNode.setCreator(jobNumber); + machineNode.setTenantId(tenantId); + machineNode.setProjectSource(SYNC_PROJECT_SOURCE); + machineNode.setPid(phaseNode.getUuid()); + addNodeList.add(machineNode); + if (machineNum.equals(machineNumber)) { + req.setMachineId(machineNode.getUuid()); + } + // 从EP拉取机台时,创建一个工位,一个机台建一个工位,用机台的编号加上M,例如01机台,工位名称和工位号都叫 01-M + SpdmProjectNodeEditReq fixedWorkspaceNode = new SpdmProjectNodeEditReq(); + fixedWorkspaceNode.setUuid(RandomUtil.generateString(32)); + fixedWorkspaceNode.setNodeCode(machineNumber + "-M"); + fixedWorkspaceNode.setNodeName(machineNumber + "-M"); + fixedWorkspaceNode.setNodeType(NodeTypeEnum.WORKSPACE.getValue()); + fixedWorkspaceNode.setCreateTime(curDateStr); + fixedWorkspaceNode.setCreator(jobNumber); + fixedWorkspaceNode.setTenantId(tenantId); + fixedWorkspaceNode.setProjectSource(SYNC_PROJECT_SOURCE); + fixedWorkspaceNode.setPid(machineNode.getUuid()); + addNodeList.add(fixedWorkspaceNode); + for (LyricVProjectStationToDM lyricVProjectStationToDM : projectStationByMachineNumberList) { + SpdmProjectNodeEditReq workspaceNode = new SpdmProjectNodeEditReq(); + workspaceNode.setUuid(RandomUtil.generateString(32)); + workspaceNode.setNodeCode(lyricVProjectStationToDM.getStationNum()); + workspaceNode.setNodeName(lyricVProjectStationToDM.getStationName()); + workspaceNode.setNodeType(NodeTypeEnum.WORKSPACE.getValue()); + workspaceNode.setCreateTime(curDateStr); + workspaceNode.setCreator(jobNumber); + workspaceNode.setTenantId(tenantId); + workspaceNode.setProjectSource(SYNC_PROJECT_SOURCE); + workspaceNode.setPid(machineNode.getUuid()); + addNodeList.add(workspaceNode); + if (stationNum.equals(workspaceNode.getNodeCode())) { + req.setWorkspaceId(workspaceNode.getUuid()); + } + } + } + } + + List tagMap = new ArrayList<>(); + TaskNodeTag projectTaskNodeTag = new TaskNodeTag(); + projectTaskNodeTag.setKey(NodeTypeEnum.PROJECT.getValue()); + projectTaskNodeTag.setValue("tag1"); + TaskNodeTag phaseTaskNodeTag = new TaskNodeTag(); + phaseTaskNodeTag.setKey(NodeTypeEnum.PHASE.getValue()); + phaseTaskNodeTag.setValue("tag2"); + TaskNodeTag machineTaskNodeTag = new TaskNodeTag(); + machineTaskNodeTag.setKey(NodeTypeEnum.MACHINE.getValue()); + machineTaskNodeTag.setValue("tag4"); + TaskNodeTag workspaceTaskNodeTag = new TaskNodeTag(); + workspaceTaskNodeTag.setKey(NodeTypeEnum.WORKSPACE.getValue()); + workspaceTaskNodeTag.setValue("tag5"); + tagMap.add(projectTaskNodeTag); + tagMap.add(phaseTaskNodeTag); + tagMap.add(machineTaskNodeTag); + tagMap.add(workspaceTaskNodeTag); + for (TaskNodeTag tagReq : tagMap) { + String currentNodeType = tagReq.getKey(); // project phase + log.info("当前nodeType为:{},tag为:{}", currentNodeType, tagReq.getValue()); + currentNodeList = addNodeList.stream().filter(node -> node.getNodeType().equals(currentNodeType)).toList(); // projectNodeList phaseNodeList + if (CollectionUtils.isEmpty(currentNodeList)) { + log.error("addNodeList中不存在{}类型的节点", currentNodeType); + continue; + } + SpdmProjectNodeEditReq eachSpdmProjectNodeEditReq; + String tagListProperty; + for (SpdmProjectNodeEditReq addNode : currentNodeList) { + if (StringUtils.isBlank(addNode.getUuid())) { + addNode.setUuid(RandomUtil.generateString(32)); + } + String pid = addNode.getPid(); + if (StringUtils.isBlank(pid)) { + try { + // tagReq.getValue()="Tag1" + setTagProperty(addNode, tagReq.getValue(), addNode.getUuid()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + // 复制父节点的tag + eachSpdmProjectNodeEditReq = addNodeList.stream().filter(node -> pid.equals(node.getUuid())).findFirst().orElse(null); + if (ObjectUtils.isNotEmpty(eachSpdmProjectNodeEditReq)) { + for (int i = 1; i <= 10; i++) { + try { + tagListProperty = getTagProperty(eachSpdmProjectNodeEditReq, "tag" + i); + if (StringUtils.isBlank(tagListProperty)) { + continue; + } + setTagProperty(addNode, "tag" + i, tagListProperty); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + try { + // tagReq.getValue()="Tag1" + setTagProperty(addNode, tagReq.getValue(), addNode.getUuid()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // 设置 当前节点所属项目根节点uuid + // addNode.getPid()为空时,在创建项目,ownRootNodeUuid就是addNode本身uuid + // addNode.getPid()不为空时,在创建阶段,ownRootNodeUuid就是入参的pid父节点 + addNode.setOwnRootNodeUuid(ObjectUtils.isEmpty(addNode.getPid()) ? addNode.getUuid() : addNode.getPid()); + addNode.setCreateTime(curDateStr); + addNode.setCreator(jobNumber); + addNode.setTenantId(tenantId); + } + } + + if (nodeMapper.addNodeBatch(addNodeList) <= 0) { + return; } // 批量创建文件夹 @@ -3531,4 +3711,309 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } + @Override + public SdmResponse acceptTodoInfo(SpdmAcceptTodoInfoReq acceptTodoInfoReq) { + log.info("acceptTodoInfo params: {}", acceptTodoInfoReq); + if (ObjectUtils.isEmpty(acceptTodoInfoReq)) { + log.error("acceptTodoInfo params empty"); + return SdmResponse.failed(ResultCode.VALIDATE_FAILED); + } + String projectNum = acceptTodoInfoReq.getProjectNum(); + String machineNum = acceptTodoInfoReq.getMachineNum(); + String stationNum = acceptTodoInfoReq.getStationNum(); + String materialNo = acceptTodoInfoReq.getMaterialNo(); + // 根据事业部(项目承接主体)查询人,相关的人都设置为此用户 + LyricVProjectToDM lyricVProjectToDM = lyricVProjectToDmService.lambdaQuery().eq(LyricVProjectToDM::getProjectNum, projectNum).one(); + if (ObjectUtils.isEmpty(lyricVProjectToDM)) { + log.error("acceptTodoInfo lyricVProjectToDM empty,projectNum: {}", projectNum); + return SdmResponse.failed(ResultCode.FAILED); + } + if (StringUtils.isBlank(lyricVProjectToDM.getProjectUndertaker())) { + log.error("acceptTodoInfo projectUndertaker empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + SysDeptUserResp sysDeptUserResp = queryMemberByGroup(lyricVProjectToDM.getProjectUndertaker(), lyricVProjectToDM.getStage()); + if (ObjectUtils.isEmpty(sysDeptUserResp)) { + log.error("acceptTodoInfo sysDeptUserResp empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + CIDUserResp cidUserResp = sysDeptUserResp.getUserResp(); + if (ObjectUtils.isEmpty(cidUserResp)) { + log.error("acceptTodoInfo cidUserResp empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + Long userId = cidUserResp.getUserId(); + Long tenantId = cidUserResp.getTenantId(); + String jobNumber = cidUserResp.getJobNumber(); + String userName = cidUserResp.getUsername(); + ThreadLocalContext.setTenantId(tenantId); + ThreadLocalContext.setUserId(userId); + ThreadLocalContext.setJobNumber(jobNumber); + ThreadLocalContext.setUserName(userName); + + // 根据项目号查询项目,如何系统不存在就先去拉取项目信息 + List projectNodeList = nodeService.lambdaQuery().eq(SimulationNode::getNodeCode, projectNum).eq(SimulationNode::getNodeType, NodeTypeEnum.PROJECT) + .list(); + SpdmAddDemandReq req = new SpdmAddDemandReq(); + req.setCreator(userId); + req.setTenantId(tenantId); + String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + if (CollectionUtils.isEmpty(projectNodeList)) { + // 拉取项目 + log.info("项目:{}在系统中不存在,拉取项目信息", projectNum); + List spdmProjectNodeEditReqList = syncProjectInfo(lyricVProjectToDM, tenantId, userId, jobNumber, userName); + if (CollectionUtils.isEmpty(spdmProjectNodeEditReqList)) { + log.error("acceptTodoInfo spdmProjectNodeEditReqList empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + SpdmProjectNodeEditReq projectNodeEditReq = spdmProjectNodeEditReqList.stream().filter(node -> NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())) + .findFirst().orElse(null); + if (projectNodeEditReq == null) { + log.error("acceptTodoInfo projectNodeEditReq empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + req.setProjectId(projectNodeEditReq.getUuid()); + SpdmProjectNodeEditReq phaseNodeEditReq = spdmProjectNodeEditReqList.stream().filter(node -> NodeTypeEnum.PHASE.getValue().equals(node.getNodeType())) + .findFirst().orElse(null); + if (phaseNodeEditReq == null) { + log.error("acceptTodoInfo phaseNodeEditReq empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + req.setPhaseId(phaseNodeEditReq.getUuid()); + SpdmProjectNodeEditReq machineNodeEditReq = spdmProjectNodeEditReqList.stream().filter(node -> NodeTypeEnum.MACHINE.getValue().equals(node.getNodeType())) + .findFirst().orElse(null); + if (machineNodeEditReq == null) { + log.error("acceptTodoInfo machineNodeEditReq empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + req.setMachineId(machineNodeEditReq.getUuid()); + SpdmProjectNodeEditReq workspaceNodeEditReq = spdmProjectNodeEditReqList.stream().filter(node -> NodeTypeEnum.WORKSPACE.getValue().equals(node.getNodeType())) + .findFirst().orElse(null); + if (workspaceNodeEditReq == null) { + log.error("acceptTodoInfo workspaceNodeEditReq empty"); + return SdmResponse.failed(ResultCode.FAILED); + } + req.setWorkspaceId(workspaceNodeEditReq.getUuid()); + } else { + if (projectNodeList.size() > 1) { + log.error("acceptTodoInfo projectNodeList too much"); + return SdmResponse.failed(ResultCode.FAILED); + } + SimulationNode projectNode = projectNodeList.get(0); + // 查询当前阶段,如果不存在,去同步当前阶段 + String currenPhase = lyricVProjectToDM.getStage(); + SimulationNode phaseNode = nodeService.lambdaQuery().eq(SimulationNode::getNodeCode, currenPhase) + .eq(SimulationNode::getTag1, projectNum) + .eq(SimulationNode::getNodeType, NodeTypeEnum.PHASE) + .one(); + if (ObjectUtils.isEmpty(phaseNode)) { + // 同步当前阶段 + syncTodoPhaseForMes(curDateStr, Long.valueOf(projectNode.getProjectId()), currenPhase, projectNode.getUuid(), req, + machineNum, stationNum); + } + } + + + req.setCreateTime(curDateStr); + req.setUuid(RandomUtil.generateString(32)); + if (demandMapper.addDemand(req, tenantId, userId) <= 0) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return SdmResponse.failed("新增需求失败!"); + } + long demandId = req.getId(); + log.info("acceptTodoInfo 需求主键id为:{}", demandId); + List allMemberList = new ArrayList<>(); + String uuid = req.getUuid(); + SpdmDemandRelateMemberReq principalDemandRelateMemberReq = new SpdmDemandRelateMemberReq(); + principalDemandRelateMemberReq.setDemandId(uuid); + principalDemandRelateMemberReq.setType(MemberTypeEnum.PRINCIPAL.getCode()); + principalDemandRelateMemberReq.setUserId(userId); + principalDemandRelateMemberReq.setCreateTime(curDateStr); + principalDemandRelateMemberReq.setCreator(userId); + allMemberList.add(principalDemandRelateMemberReq); + + SpdmDemandRelateMemberReq threedDemandRelateMemberReq = new SpdmDemandRelateMemberReq(); + threedDemandRelateMemberReq.setDemandId(uuid); + threedDemandRelateMemberReq.setType(MemberTypeEnum.THREED.getCode()); + threedDemandRelateMemberReq.setUserId(userId); + threedDemandRelateMemberReq.setCreateTime(curDateStr); + threedDemandRelateMemberReq.setCreator(userId); + allMemberList.add(threedDemandRelateMemberReq); + + if (CollectionUtils.isNotEmpty(allMemberList)) { + if (demandMapper.addDemandMember(allMemberList) <= 0) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return SdmResponse.failed("新增需求关联成员失败!"); + } + } + + // 需求额外属性(物料号) + SpdmDemandExtraReq spdmDemandExtraReq = new SpdmDemandExtraReq(); + spdmDemandExtraReq.setPropertyName("materialNo"); + spdmDemandExtraReq.setPropertyValue(materialNo); + List demandExtraList = Collections.singletonList(spdmDemandExtraReq); + if (CollectionUtils.isNotEmpty(demandExtraList)) { + demandExtraList.forEach(demandExtra -> { + demandExtra.setDemandId(req.getUuid()); + demandExtra.setCreateTime(curDateStr); + demandExtra.setCreator(userId); + }); + if (demandMapper.addDemandExtra(demandExtraList) <= 0) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return SdmResponse.failed("新增需求额外属性失败!"); + } + } + + // 项目层级文件夹和需求文件夹中,新增一层【需求附件】文件夹 + String projectNodeId = req.getProjectId(); + BatchCreateNormalDirReq batchCreateNormalDirReq = new BatchCreateNormalDirReq(); + SdmResponse fileMetadataInfoResp = dataFeignClient.queryFileMetadataInfo(projectNodeId, NodeTypeEnum.PROJECT.getValue(), 0L); + if (fileMetadataInfoResp.getData() == null) { + log.error("acceptTodoInfo fileMetadataInfoResp为空,projectNodeId为:{}", projectNodeId); + return SdmResponse.failed("新增需求失败!"); + } + // 查询需求附件的uuid,元数据表中【parentId是project的元数据主键id且originalName为:需求附件】 + FileMetadataInfoResp projectMetadataInfo = fileMetadataInfoResp.getData(); + SdmResponse> listSdmResponse = dataFeignClient.listDir(DirTypeEnum.PROJECT_NODE_DIR.getValue(), projectMetadataInfo.getId()); + if (!listSdmResponse.isSuccess() || CollectionUtils.isEmpty(listSdmResponse.getData())) { + log.error("acceptTodoInfo listSdmResponse为空,project的元数据主键id为:{}", projectMetadataInfo.getId()); + return SdmResponse.failed("新增需求失败!"); + } + List childrenMetadataInfoList = listSdmResponse.getData(); + FileMetadataInfoResp demandAttachFileMetadataInfoResp = childrenMetadataInfoList.stream().filter(metadataInfo -> AttachFileTypeEnum.DEMAND_FILE.getValue().equals(metadataInfo.getOriginalName())).findFirst().orElse(null); + Long demandAttachFileMetadataInfoId; + if (ObjectUtils.isEmpty(demandAttachFileMetadataInfoResp)) { + log.info("acceptTodoInfo 未查询到需求附件文件夹,当前项目下的子文件夹为:{}", childrenMetadataInfoList); + // 项目层级文件夹和需求文件夹中,新增一层【需求附件】文件夹 + List demandAttachFolderItemReqList = new ArrayList<>(); + BatchCreateNormalDirReq demandAttachBatchCreateNormalDirReq = new BatchCreateNormalDirReq(); + demandAttachBatchCreateNormalDirReq.setParentUUId(projectNodeId); + FolderItemReq demandAttachFolderItemReq = new FolderItemReq(); + demandAttachFolderItemReq.setFolderName(AttachFileTypeEnum.DEMAND_FILE.getValue()); + demandAttachFolderItemReq.setFolderUuid(RandomUtil.generateString(32)); + demandAttachFolderItemReqList.add(demandAttachFolderItemReq); + demandAttachBatchCreateNormalDirReq.setFolderItems(demandAttachFolderItemReqList); + log.info("acceptTodoInfo 创建需求附件文件夹请求参数:{}", demandAttachBatchCreateNormalDirReq); + BatchCreateNormalDirResp batchCreateNormalDirResp; + try { + SdmResponse response = dataFeignClient.batchCreateNormalDirs(demandAttachBatchCreateNormalDirReq); + log.info("acceptTodoInfo 创建需求附件文件夹响应:{}", response); + if (!response.isSuccess() || ObjectUtils.isEmpty(response.getData())) { + log.error("acceptTodoInfo 调用创建需求附件文件夹接口失败,原因为:{}", response.getMessage()); + return SdmResponse.failed("创建需求附件文件夹失败:,原因为:" + response.getMessage()); + } + batchCreateNormalDirResp = response.getData(); + } catch (Exception e) { + log.error("调用创建需求附件文件夹接口失败", e); + return SdmResponse.failed("创建需求附件文件夹失败:" + e.getMessage()); + } + + if (ObjectUtils.isEmpty(batchCreateNormalDirResp)) { + log.error("batchCreateNormalDirResp为空"); + return SdmResponse.failed("创建需求附件文件夹失败"); + } + List successList = batchCreateNormalDirResp.getSuccessList(); + if (CollectionUtils.isEmpty(successList)) { + log.error("successList为空"); + return SdmResponse.failed("创建需求附件文件夹失败"); + } + // 需求附件文件夹的元数据主键id + demandAttachFileMetadataInfoId = successList.get(0).getId(); + } else { + demandAttachFileMetadataInfoId = demandAttachFileMetadataInfoResp.getId(); + } + batchCreateNormalDirReq.setParentId(demandAttachFileMetadataInfoId); + FolderItemReq folderItemReq = new FolderItemReq(); + folderItemReq.setFolderName(req.getDemandName()); + folderItemReq.setFolderUuid(req.getUuid()); + batchCreateNormalDirReq.setFolderItems(Collections.singletonList(folderItemReq)); + log.info("acceptTodoInfo 创建文件夹参数: {}", batchCreateNormalDirReq); + SdmResponse dirCreateResp = dataFeignClient.batchCreateNormalDirs(batchCreateNormalDirReq); + if (ObjectUtils.isEmpty(dirCreateResp) || dirCreateResp.getCode() != ResultCode.SUCCESS.getCode()) { + log.error("acceptTodoInfo 手动创建{}项目下的{}需求时,创建文件夹失败,原因为:{}", req.getProjectId(), req.getDemandName(), dirCreateResp.getMessage()); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return SdmResponse.failed("您没有选择项目的相应权限,请更换其他项目进行创建"); + } + log.info("acceptTodoInfo 创建文件夹响应: {}", dirCreateResp); + + // 更新需求创建人对需求文件夹的权限 & 更新需求仿真负责人(确认人)对需求文件夹的权限(预览、下载) + UpdatePermissionReq updatePermissionReq = new UpdatePermissionReq(); + updatePermissionReq.setUuid(uuid); + Map userPermissions = new HashMap<>(); + // 创建人 + userPermissions.put(userId, FilePermissionEnum.ALL.getValue()); + // 仿真负责人 + if (CollectionUtils.isNotEmpty(allMemberList)) { + allMemberList.stream().filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType())).forEach(member -> { + userPermissions.put(member.getUserId(), FilePermissionEnum.BASE.getValue()); + }); + } + // 仿真负责人还需要对选择的节点有创建和预览权限 + UpdatePermissionReq updateNodePermissionReq = new UpdatePermissionReq(); + updateNodePermissionReq.setUuid(req.getWorkspaceId()); + Map userForNodePermissions = new HashMap<>(); + userForNodePermissions.put(userId, FilePermissionEnum.ALL_EXCLUDE_DELETE.getValue()); + updateNodePermissionReq.setUserPermissions(userForNodePermissions); + log.info("acceptTodoInfo,更新需求仿真负责人(确认人)工位节点权限的参数为:{}", updateNodePermissionReq); + SdmResponse updateNodePermissionResponse = dataFeignClient.updatePermission(updateNodePermissionReq); + log.info("acceptTodoInfo,更新需求仿真负责人(确认人)工位节点权限的返回值为:{}", updateNodePermissionResponse); + + + log.info("acceptTodoInfo,更新需求创建人和需求仿真负责人(确认人)权限的参数为:{}", updatePermissionReq); + SdmResponse updatePermissionResponse = dataFeignClient.updatePermission(updatePermissionReq); + log.info("acceptTodoInfo,更新需求创建人和需求仿真负责人(确认人)权限的返回值为:{}", updatePermissionResponse); + + SimulationDemand demand = new SimulationDemand(); + BeanUtils.copyProperties(req, demand); + simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand)); + + return SdmResponse.success(req.getUuid()); + } + + /** + * 项目的当前阶段包含:设计,就是:项目承接主体+结构,否则就是:项目承接主体+技术中心+结构,所对应的人 + * + * @param projectUndertaker + * @return + */ + private SysDeptUserResp queryMemberByGroup(String projectUndertaker, String currenPhase) { + String deptName; + if (DESIGN_PHASE.equals(currenPhase)) { + deptName = projectUndertaker + "-" + STRUCTURE; + } else { + deptName = projectUndertaker + "-" + TECHNOLOGY_CENTER + "-" + STRUCTURE; + } + // 待调用system的查询部门用户feign接口 + return null; + } + + private List syncProjectInfo(LyricVProjectToDM lyricVProjectToDM, Long tenantId, Long userId, String jobNumber, String userName) { + String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + List spdmProjectNodeEditReqList = new ArrayList<>(); + try { + List allNodeManagerList = new ArrayList<>(); + SpdmProjectNodeEditReq spdmProjectNodeEditReq = buildProjectForTodoInfo(lyricVProjectToDM, tenantId, userId); + if (spdmProjectNodeEditReq != null) { + spdmProjectNodeEditReqList.add(spdmProjectNodeEditReq); + for (Long epFixManagerUserId : epFixManagerUserIdList) { + SpdmNodeRelateMemberReq simulationNodeMember = new SpdmNodeRelateMemberReq(); + simulationNodeMember.setNodeId(spdmProjectNodeEditReq.getUuid()); + simulationNodeMember.setUserId(epFixManagerUserId); + simulationNodeMember.setCreator(userId); + simulationNodeMember.setCreateTime(curDateStr); + simulationNodeMember.setType(NodeMemberTypeEnum.MANAGER.getCode()); + allNodeManagerList.add(simulationNodeMember); + } + } + if (CollectionUtils.isNotEmpty(allNodeManagerList)) { + nodeMapper.addNodeMemberBatch(allNodeManagerList); + } + } catch (Exception e) { + log.error("syncProjectInfo 未知 error: {}", e.getMessage()); + return new ArrayList<>(); + } + return spdmProjectNodeEditReqList; + } + + }