Merge remote-tracking branch 'origin/main'
This commit is contained in:
1
1-sql/2026-01-24/project/simulation_node.sql
Normal file
1
1-sql/2026-01-24/project/simulation_node.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE simulation_node ADD referenceItem varchar(100) NULL COMMENT '参考项目';
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.sdm.project.config.thread;
|
||||
|
||||
import com.sdm.common.mdc.MdcTaskDecorator;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 用于批量创建需求、需求拓展属性、更新权限(最好直接使用批量更新接口)使用的线程池
|
||||
*/
|
||||
@Configuration
|
||||
public class ProjectTaskThreadPool {
|
||||
|
||||
@Value("${projectTaskPool.coreSize:20}")
|
||||
private int CORE_POOL_SIZE ;
|
||||
|
||||
@Value("${projectTaskPool.maxSize:60}")
|
||||
private int MAX_POOL_SIZE ;
|
||||
|
||||
@Value("${projectTaskPool.queueSize:5000}")
|
||||
private int QUEUE_CAPACITY ;
|
||||
|
||||
@Value("${projectTaskPool.keepLive:60}")
|
||||
private int KEEP_ALIVE_SECONDS ;
|
||||
|
||||
@Value("${projectTaskPool.threadName:projectTaskPool-}")
|
||||
private String THREAD_NAME_PREFIX ;
|
||||
|
||||
@Bean(name = "projectTaskThreadPoolExecutor")
|
||||
public Executor projectTaskThreadPoolExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(CORE_POOL_SIZE);
|
||||
executor.setMaxPoolSize(MAX_POOL_SIZE);
|
||||
executor.setQueueCapacity(QUEUE_CAPACITY);
|
||||
executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
|
||||
executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
executor.setTaskDecorator(new MdcTaskDecorator());
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -155,7 +155,7 @@ public class SimulationNode implements Serializable {
|
||||
@TableField("commitmentDeadline")
|
||||
private String commitmentDeadline;
|
||||
|
||||
@TableField("reference_item")
|
||||
@TableField("referenceItem")
|
||||
private String referenceItem;
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -52,6 +53,7 @@ import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
@@ -70,6 +72,12 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
|
||||
|
||||
private static final String ZIP_SUFFIX = ".zip";
|
||||
|
||||
private static final String CACHE_NAME_SYNC_TODO = "syncTodo";
|
||||
private static final String CACHE_KEY_TODO = "todo";
|
||||
private static final long SYNC_INTERVAL_MS = 30 * 1000L;
|
||||
private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
private static final int UUID_LENGTH = 32;
|
||||
|
||||
@Autowired
|
||||
private LyricIntegrateService lyricIntegrateService;
|
||||
|
||||
@@ -112,6 +120,10 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("projectTaskThreadPoolExecutor")
|
||||
private Executor projectTaskThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 判断字符串是否可以安全转换为Long类型
|
||||
*
|
||||
@@ -186,374 +198,385 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
|
||||
return lyricIntegrateService.getProcessData(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getTodoList() {
|
||||
Cache todoCache = cacheManager.getCache("syncTodo");
|
||||
/**
|
||||
* 校验同步缓存:控制同步频率
|
||||
*/
|
||||
private SdmResponse checkSyncCache() {
|
||||
Cache todoCache = cacheManager.getCache(CACHE_NAME_SYNC_TODO);
|
||||
if (todoCache == null) {
|
||||
return SdmResponse.failed("未查询到缓存");
|
||||
}
|
||||
boolean flag = false;
|
||||
if (todoCache.get("todo") == null) {
|
||||
todoCache.put("todo",System.currentTimeMillis());
|
||||
flag = true;
|
||||
|
||||
boolean isFirstSync = todoCache.get(CACHE_KEY_TODO) == null;
|
||||
if (isFirstSync) {
|
||||
todoCache.put(CACHE_KEY_TODO, System.currentTimeMillis());
|
||||
return null;
|
||||
}
|
||||
Long lastSyncTime = (Long) todoCache.get("todo").get();
|
||||
if (!flag && ObjectUtils.isNotEmpty(lastSyncTime) && System.currentTimeMillis() - lastSyncTime < 30 * 1000) {
|
||||
|
||||
Long lastSyncTime = (Long) todoCache.get(CACHE_KEY_TODO).get();
|
||||
if (ObjectUtils.isNotEmpty(lastSyncTime)
|
||||
&& System.currentTimeMillis() - lastSyncTime < SYNC_INTERVAL_MS) {
|
||||
return SdmResponse.failed("刚刚已同步过需求,请稍后再试");
|
||||
}
|
||||
todoCache.put("todo",System.currentTimeMillis());
|
||||
List<SimulationNode> nodeList = nodeService.lambdaQuery()
|
||||
.eq(SimulationNode::getNodeType,NodeTypeEnum.PROJECT.getValue()).eq(SimulationNode::getProjectSource, SYNC_PROJECT_SOURCE).list();
|
||||
if (CollectionUtils.isEmpty(nodeList)) {
|
||||
log.info("getTodoList中nodeList为空");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<String> nodeCodeList = nodeList.stream().map(SimulationNode::getNodeCode).toList();
|
||||
log.info("nodeCodeList为:{}", nodeCodeList);
|
||||
if (CollectionUtils.isEmpty(nodeCodeList)) {
|
||||
log.info("getTodoList中nodeCodeList为空");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
// 查询
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList = lyricVTodoInfoService.lambdaQuery().in(LyricVTodoEmulationInfoDM::getProject, nodeCodeList)
|
||||
|
||||
// 更新同步时间
|
||||
todoCache.put(CACHE_KEY_TODO, System.currentTimeMillis());
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询有效的项目节点列表
|
||||
*/
|
||||
private List<SimulationNode> queryProjectNodeList() {
|
||||
return nodeService.lambdaQuery()
|
||||
.eq(SimulationNode::getNodeType, NodeTypeEnum.PROJECT.getValue())
|
||||
.eq(SimulationNode::getProjectSource, SYNC_PROJECT_SOURCE)
|
||||
.list()
|
||||
.stream()
|
||||
.filter(node -> StringUtils.isNotBlank(node.getNodeCode())) // 过滤无效编码
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询待办数据并过滤已同步的数据
|
||||
*/
|
||||
private List<LyricVTodoEmulationInfoDM> queryAndFilterTodoList(List<String> projectCodeList) {
|
||||
// 查询原始待办数据
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList = lyricVTodoInfoService.lambdaQuery()
|
||||
.in(LyricVTodoEmulationInfoDM::getProject, projectCodeList)
|
||||
.list();
|
||||
// 过滤掉数据库中已经有的需求
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("未手动同步到待办");
|
||||
return SdmResponse.success();
|
||||
log.info("未查询到待同步的待办数据");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
log.info("手动同步到{}条待办", todoInfoList.size());
|
||||
|
||||
// 过滤已同步的待办
|
||||
List<SpdmDemandVo> allDemandList = demandMapper.getAllList();
|
||||
log.info("allDemandList:{}", allDemandList);
|
||||
if (CollectionUtils.isNotEmpty(allDemandList)) {
|
||||
List<String> demandCodeList = allDemandList.stream().map(SpdmDemandVo::getDemandCode).toList();
|
||||
todoInfoList = todoInfoList.stream().filter(todoInfo -> !demandCodeList.contains(String.valueOf(todoInfo.getTodoId()))).toList();
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("本次手动同步到的待办都已经进行过同步");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
if (CollectionUtils.isEmpty(allDemandList)) {
|
||||
return todoInfoList;
|
||||
}
|
||||
|
||||
Set<String> existDemandCodeSet = allDemandList.stream()
|
||||
.map(SpdmDemandVo::getDemandCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<LyricVTodoEmulationInfoDM> filterTodoList = todoInfoList.stream()
|
||||
.filter(todoInfo -> !existDemandCodeSet.contains(String.valueOf(todoInfo.getTodoId())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(filterTodoList)) {
|
||||
log.info("本次手动同步到的待办都已经进行过同步");
|
||||
}
|
||||
return filterTodoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心同步逻辑:构建数据并执行批量操作
|
||||
*/
|
||||
private SdmResponse syncTodoData(List<SimulationNode> projectNodeList,
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList) {
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
Long jobNumber = ThreadLocalContext.getUserId();
|
||||
String uuid;
|
||||
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
String curDateStr = new SimpleDateFormat(DATE_FORMAT_PATTERN).format(new Date());
|
||||
|
||||
// 构建批量创建文件夹参数 + 权限更新参数
|
||||
List<BatchCreateDirItem> createDirItemList = new ArrayList<>();
|
||||
List<UpdatePermissionReq> currentUpdatePermissionList = new ArrayList<>();
|
||||
for (LyricVTodoEmulationInfoDM emulation : todoInfoList) {
|
||||
List<UpdatePermissionReq> updatePermissionList = new ArrayList<>();
|
||||
|
||||
// 按项目分组处理待办
|
||||
Map<String, List<LyricVTodoEmulationInfoDM>> projectTodoMap = todoInfoList.stream()
|
||||
.collect(Collectors.groupingBy(LyricVTodoEmulationInfoDM::getProject));
|
||||
|
||||
for (SimulationNode projectNode : projectNodeList) {
|
||||
String projectCode = projectNode.getNodeCode();
|
||||
List<LyricVTodoEmulationInfoDM> projectTodoList = projectTodoMap.getOrDefault(projectCode, Collections.emptyList());
|
||||
if (CollectionUtils.isEmpty(projectTodoList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 构建项目级文件夹参数
|
||||
BatchCreateDirItem projectCreateItem = buildProjectDirItem(projectNode);
|
||||
List<DirNodeInfo> demandDirNodeList = new ArrayList<>();
|
||||
|
||||
// 处理当前项目下的所有待办
|
||||
for (LyricVTodoEmulationInfoDM todo : projectTodoList) {
|
||||
try {
|
||||
String demandUuid = RandomUtil.generateString(UUID_LENGTH);
|
||||
// 1. 构建需求基础参数 + 成员 + 权限
|
||||
SpdmAddDemandReq demandReq = buildDemandReq(todo, demandUuid, curDateStr);
|
||||
List<SpdmDemandRelateMemberReq> memberList = buildDemandMemberList(todo, demandUuid, jobNumber, curDateStr);
|
||||
// 2. 构建权限更新参数
|
||||
buildPermissionReqList(demandUuid, jobNumber, todo, updatePermissionList);
|
||||
// 3. 构建需求文件夹节点
|
||||
demandDirNodeList.add(buildDemandDirNode(demandUuid, projectNode, demandReq.getDemandName()));
|
||||
// 4. 异步保存需求数据
|
||||
asyncSaveDemandData(demandReq, memberList, tenantId, jobNumber);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理项目[{}]下待办[{}]异常: ", projectCode, todo.getTodoId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定需求文件夹到项目
|
||||
projectCreateItem.setChildDirNodeInfos(demandDirNodeList);
|
||||
createDirItemList.add(projectCreateItem);
|
||||
}
|
||||
|
||||
// 执行批量操作
|
||||
executeBatchOperations(createDirItemList, updatePermissionList);
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建项目级文件夹创建参数
|
||||
*/
|
||||
private BatchCreateDirItem buildProjectDirItem(SimulationNode projectNode) {
|
||||
BatchCreateDirItem item = new BatchCreateDirItem();
|
||||
DirNodeInfo projectDirNode = new DirNodeInfo();
|
||||
projectDirNode.setUuId(projectNode.getUuid());
|
||||
projectDirNode.setParentUuId(null);
|
||||
projectDirNode.setUuIdOwnType(NodeTypeEnum.PROJECT.getValue());
|
||||
projectDirNode.setDirName(projectNode.getNodeName());
|
||||
item.setParentDirNodeInfo(projectDirNode);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建需求基础参数
|
||||
*/
|
||||
private SpdmAddDemandReq buildDemandReq(LyricVTodoEmulationInfoDM todo,
|
||||
String demandUuid,
|
||||
String curDateStr) {
|
||||
SpdmAddDemandReq req = new SpdmAddDemandReq();
|
||||
req.setUuid(demandUuid);
|
||||
req.setDemandName(todo.getSubject());
|
||||
req.setDemandCode(ObjectUtils.isNotEmpty(todo.getTodoId()) ? String.valueOf(todo.getTodoId()) : null);
|
||||
req.setDemandType(todo.getEmulationType());
|
||||
req.setSimType(todo.getRelevanceTask());
|
||||
req.setDemandStatus("0");
|
||||
req.setAchieveStatus("0");
|
||||
req.setProgress(0);
|
||||
req.setBeginTime(todo.getPlanStartTime());
|
||||
req.setEndTime(todo.getClosedTime());
|
||||
req.setCreateTime(curDateStr);
|
||||
req.setDemandSource(SYNC_PROJECT_SOURCE);
|
||||
|
||||
// 补充项目/阶段/工位ID
|
||||
fillProjectPhaseWorkspaceId(req, todo);
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充需求的项目/阶段/工位ID
|
||||
*/
|
||||
private void fillProjectPhaseWorkspaceId(SpdmAddDemandReq req, LyricVTodoEmulationInfoDM todo) {
|
||||
List<SimulationNode> allNodeList = nodeService.lambdaQuery()
|
||||
.in(SimulationNode::getNodeCode, Arrays.asList(todo.getProject(), todo.getProjectStage(), todo.getStationNum()))
|
||||
.list();
|
||||
|
||||
if (CollectionUtils.isEmpty(allNodeList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
allNodeList.stream()
|
||||
.filter(node -> NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())
|
||||
&& node.getNodeCode().equals(todo.getProject()))
|
||||
.findFirst()
|
||||
.ifPresent(node -> req.setProjectId(node.getUuid()));
|
||||
|
||||
allNodeList.stream()
|
||||
.filter(node -> NodeTypeEnum.PHASE.getValue().equals(node.getNodeType())
|
||||
&& node.getNodeCode().equals(todo.getProjectStage()))
|
||||
.findFirst()
|
||||
.ifPresent(node -> req.setPhaseId(node.getUuid()));
|
||||
|
||||
allNodeList.stream()
|
||||
.filter(node -> NodeTypeEnum.WORKSPACE.getValue().equals(node.getNodeType())
|
||||
&& node.getNodeCode().equals(todo.getStationNum()))
|
||||
.findFirst()
|
||||
.ifPresent(node -> req.setNodeId(node.getUuid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建需求关联成员列表
|
||||
*/
|
||||
private List<SpdmDemandRelateMemberReq> buildDemandMemberList(LyricVTodoEmulationInfoDM todo,
|
||||
String demandUuid,
|
||||
Long jobNumber,
|
||||
String curDateStr) {
|
||||
List<SpdmDemandRelateMemberReq> memberList = new ArrayList<>();
|
||||
|
||||
// 仿真负责人
|
||||
addDemandMember(todo.getEmulationPerformer(), 0, demandUuid, jobNumber, curDateStr, memberList);
|
||||
// 仿真执行人
|
||||
addDemandMember(todo.getEmulationExecutor(), 1, demandUuid, jobNumber, curDateStr, memberList);
|
||||
// 3D负责人
|
||||
addDemandMember(todo.getThreeDimensionalPerformer(), 2, demandUuid, jobNumber, curDateStr, memberList);
|
||||
|
||||
return memberList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用添加需求成员方法
|
||||
*/
|
||||
private void addDemandMember(String memberStr,
|
||||
int type,
|
||||
String demandUuid,
|
||||
Long jobNumber,
|
||||
String curDateStr,
|
||||
List<SpdmDemandRelateMemberReq> memberList) {
|
||||
if (StringUtils.isBlank(memberStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SpdmDemandRelateMemberReq memberReq = new SpdmDemandRelateMemberReq();
|
||||
memberReq.setDemandId(demandUuid);
|
||||
memberReq.setType(type);
|
||||
memberReq.setCreateTime(curDateStr);
|
||||
memberReq.setCreator(jobNumber);
|
||||
|
||||
String userIdStr = memberStr.split("-")[0];
|
||||
if (isConvertibleToLong(userIdStr)) {
|
||||
memberReq.setUserId(Long.valueOf(userIdStr));
|
||||
}
|
||||
|
||||
memberList.add(memberReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建权限更新请求列表
|
||||
*/
|
||||
private void buildPermissionReqList(String demandUuid,
|
||||
Long currentUserId,
|
||||
LyricVTodoEmulationInfoDM todo,
|
||||
List<UpdatePermissionReq> permissionList) {
|
||||
// 当前用户权限
|
||||
permissionList.add(buildUpdatePermissionReq(demandUuid, currentUserId));
|
||||
|
||||
// 仿真负责人权限
|
||||
addPermissionReq(todo.getEmulationPerformer(), demandUuid, permissionList);
|
||||
// 仿真执行人权限
|
||||
addPermissionReq(todo.getEmulationExecutor(), demandUuid, permissionList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建单个权限更新请求
|
||||
*/
|
||||
private UpdatePermissionReq buildUpdatePermissionReq(String uuid, Long userId) {
|
||||
UpdatePermissionReq req = new UpdatePermissionReq();
|
||||
req.setUserId(userId);
|
||||
req.setUuid(uuid);
|
||||
Map<Long, Byte> permissions = new HashMap<>();
|
||||
permissions.put(userId, FilePermissionEnum.ALL.getValue());
|
||||
req.setUserPermissions(permissions);
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员权限请求
|
||||
*/
|
||||
private void addPermissionReq(String memberStr, String demandUuid, List<UpdatePermissionReq> permissionList) {
|
||||
if (StringUtils.isBlank(memberStr)) {
|
||||
return;
|
||||
}
|
||||
String userIdStr = memberStr.split("-")[0];
|
||||
if (isConvertibleToLong(userIdStr)) {
|
||||
permissionList.add(buildUpdatePermissionReq(demandUuid, Long.valueOf(userIdStr)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建需求文件夹节点
|
||||
*/
|
||||
private DirNodeInfo buildDemandDirNode(String demandUuid,
|
||||
SimulationNode projectNode,
|
||||
String demandName) {
|
||||
DirNodeInfo dirNode = new DirNodeInfo();
|
||||
dirNode.setUuId(demandUuid);
|
||||
dirNode.setParentUuId(projectNode.getUuid());
|
||||
dirNode.setUuIdOwnType(NodeTypeEnum.DEMAND.getValue());
|
||||
dirNode.setDirName(demandName);
|
||||
return dirNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步保存需求数据(基础信息+成员+扩展属性)
|
||||
*/
|
||||
private void asyncSaveDemandData(SpdmAddDemandReq demandReq,
|
||||
List<SpdmDemandRelateMemberReq> memberList,
|
||||
Long tenantId,
|
||||
Long jobNumber) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
List<SpdmDemandExtraReq> extras = new ArrayList<>();
|
||||
List<SpdmDemandRelateMemberReq> allMemberList = new ArrayList<>();
|
||||
// 需求的基础属性
|
||||
SpdmAddDemandReq spdmAddDemandReq = new SpdmAddDemandReq();
|
||||
uuid = RandomUtil.generateString(32);
|
||||
spdmAddDemandReq.setUuid(uuid);
|
||||
spdmAddDemandReq.setDemandName(emulation.getSubject());
|
||||
if (ObjectUtils.isNotEmpty(emulation.getTodoId())) {
|
||||
spdmAddDemandReq.setDemandCode(String.valueOf(emulation.getTodoId()));
|
||||
}
|
||||
spdmAddDemandReq.setDemandType(emulation.getEmulationType());
|
||||
spdmAddDemandReq.setSimType(emulation.getRelevanceTask());
|
||||
spdmAddDemandReq.setDemandStatus("0");
|
||||
spdmAddDemandReq.setAchieveStatus("0");
|
||||
spdmAddDemandReq.setProgress(0);
|
||||
spdmAddDemandReq.setBeginTime(emulation.getPlanStartTime());
|
||||
spdmAddDemandReq.setEndTime(emulation.getClosedTime());
|
||||
|
||||
List<String> projectCodeList = todoInfoList.stream().map(LyricVTodoEmulationInfoDM::getProject).filter(StringUtils::isNotBlank).toList();
|
||||
List<SimulationNode> allNodeList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(projectCodeList)) {
|
||||
List<SimulationNode> allProjectNodeList = nodeService.lambdaQuery().in(SimulationNode::getNodeCode, projectCodeList).list();
|
||||
if (CollectionUtils.isNotEmpty(allNodeList)) {
|
||||
List<String> projectIdList = allProjectNodeList.stream().map(SimulationNode::getUuid).toList();
|
||||
allNodeList = nodeService.lambdaQuery().in(SimulationNode::getTag1,projectIdList).list();
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(allNodeList)) {
|
||||
String projectNode = emulation.getProject();
|
||||
String phaseNode = emulation.getProjectStage();
|
||||
String workspaceNode = emulation.getStationNum();
|
||||
Optional<SimulationNode> projectOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(projectNode)
|
||||
&& NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())).findFirst();
|
||||
Optional<SimulationNode> phaseOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(phaseNode)
|
||||
&& NodeTypeEnum.PHASE.getValue().equals(node.getNodeType())).findFirst();
|
||||
Optional<SimulationNode> workspaceOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(workspaceNode)
|
||||
&& NodeTypeEnum.WORKSPACE.getValue().equals(node.getNodeType())).findFirst();
|
||||
// 转换为project的uuid
|
||||
projectOptional.ifPresent(simulationNode -> spdmAddDemandReq.setProjectId(simulationNode.getUuid()));
|
||||
phaseOptional.ifPresent(simulationNode -> spdmAddDemandReq.setPhaseId(simulationNode.getUuid()));
|
||||
workspaceOptional.ifPresent(simulationNode -> spdmAddDemandReq.setNodeId(simulationNode.getUuid()));
|
||||
}
|
||||
spdmAddDemandReq.setCreateTime(curDateStr);
|
||||
spdmAddDemandReq.setDemandSource(SYNC_PROJECT_SOURCE);
|
||||
// 需求的额外属性
|
||||
// SpdmDemandExtraReq extraReq1 = new SpdmDemandExtraReq();
|
||||
// extraReq1.setDemandId(uuid);
|
||||
// extraReq1.setPropertyName("emulationResult");
|
||||
// extraReq1.setPropertyValue(emulation.getEmulationResult());
|
||||
// extras.add(extraReq1);
|
||||
// SpdmDemandExtraReq extraReq2 = new SpdmDemandExtraReq();
|
||||
// extraReq2.setDemandId(uuid);
|
||||
// extraReq2.setPropertyName("robotBrand");
|
||||
// extraReq2.setPropertyValue(emulation.getRobotBrand());
|
||||
// extras.add(extraReq2);
|
||||
// SpdmDemandExtraReq extraReq3 = new SpdmDemandExtraReq();
|
||||
// extraReq3.setDemandId(uuid);
|
||||
// extraReq3.setPropertyName("axis");
|
||||
// extraReq3.setPropertyValue(emulation.getAxis());
|
||||
// extras.add(extraReq3);
|
||||
// SpdmDemandExtraReq extraReq4 = new SpdmDemandExtraReq();
|
||||
// extraReq4.setDemandId(uuid);
|
||||
// extraReq4.setPropertyName("beatRequirements");
|
||||
// extraReq4.setPropertyValue(emulation.getBeatRequirements());
|
||||
// extras.add(extraReq4);
|
||||
// SpdmDemandExtraReq extraReq5 = new SpdmDemandExtraReq();
|
||||
// extraReq5.setDemandId(uuid);
|
||||
// extraReq5.setPropertyName("threeDimensionalReposito");
|
||||
// extraReq5.setPropertyValue(emulation.getThreeDimensionalRepositoryPath());
|
||||
// extras.add(extraReq5);
|
||||
// SpdmDemandExtraReq extraReq6 = new SpdmDemandExtraReq();
|
||||
// extraReq6.setDemandId(uuid);
|
||||
// extraReq6.setPropertyName("resultPath");
|
||||
// extraReq6.setPropertyValue(emulation.getResultPath());
|
||||
// extras.add(extraReq6);
|
||||
// SpdmDemandExtraReq extraReq7 = new SpdmDemandExtraReq();
|
||||
// extraReq7.setDemandId(uuid);
|
||||
// extraReq7.setPropertyName("resultDescribe");
|
||||
// extraReq7.setPropertyValue(emulation.getResultDescribe());
|
||||
// extras.add(extraReq7);
|
||||
// SpdmDemandExtraReq extraReq8 = new SpdmDemandExtraReq();
|
||||
// extraReq8.setDemandId(uuid);
|
||||
// extraReq8.setPropertyName("analysisType");
|
||||
// extraReq8.setPropertyValue(emulation.getAnalysisType());
|
||||
// extras.add(extraReq8);
|
||||
// SpdmDemandExtraReq extraReq11 = new SpdmDemandExtraReq();
|
||||
// extraReq11.setDemandId(uuid);
|
||||
// extraReq11.setPropertyName("software");
|
||||
// extraReq11.setPropertyValue(emulation.getSoftware());
|
||||
// extras.add(extraReq11);
|
||||
// SpdmDemandExtraReq extraReq12 = new SpdmDemandExtraReq();
|
||||
// extraReq12.setDemandId(uuid);
|
||||
// extraReq12.setPropertyName("type");
|
||||
// extraReq12.setPropertyValue(emulation.getType());
|
||||
// extras.add(extraReq12);
|
||||
// SpdmDemandExtraReq extraReq13 = new SpdmDemandExtraReq();
|
||||
// extraReq13.setDemandId(uuid);
|
||||
// extraReq13.setPropertyName("resultFileId");
|
||||
// extraReq13.setPropertyValue(emulation.getResultFileId());
|
||||
// extras.add(extraReq13);
|
||||
// SpdmDemandExtraReq extraReq14 = new SpdmDemandExtraReq();
|
||||
// extraReq14.setDemandId(uuid);
|
||||
// extraReq14.setPropertyName("difficulty");
|
||||
// extraReq14.setPropertyValue(emulation.getDifficulty());
|
||||
// extras.add(extraReq14);
|
||||
// SpdmDemandExtraReq extraReq15 = new SpdmDemandExtraReq();
|
||||
// extraReq15.setDemandId(uuid);
|
||||
// extraReq15.setPropertyName("requiredTime");
|
||||
// extraReq15.setPropertyValue(emulation.getRequiredTime());
|
||||
// extras.add(extraReq15);
|
||||
//// SpdmDemandExtraReq extraReq20 = new SpdmDemandExtraReq();
|
||||
//// extraReq20.setDemandId(uuid);
|
||||
//// extraReq20.setPropertyName("subject");
|
||||
//// extraReq20.setPropertyValue(emulation.getSubject());
|
||||
//// extras.add(extraReq20);
|
||||
// SpdmDemandExtraReq extraReq21 = new SpdmDemandExtraReq();
|
||||
// extraReq21.setDemandId(uuid);
|
||||
// extraReq21.setPropertyName("todoNum");
|
||||
// extraReq21.setPropertyValue(emulation.getTodoNum());
|
||||
// extras.add(extraReq21);
|
||||
// SpdmDemandExtraReq extraReq22 = new SpdmDemandExtraReq();
|
||||
// extraReq22.setDemandId(uuid);
|
||||
// extraReq22.setPropertyName("status");
|
||||
// extraReq22.setPropertyValue(emulation.getStatus());
|
||||
// extras.add(extraReq22);
|
||||
// SpdmDemandExtraReq extraReq26 = new SpdmDemandExtraReq();
|
||||
// extraReq26.setDemandId(uuid);
|
||||
// extraReq26.setPropertyName("projectName");
|
||||
// extraReq26.setPropertyValue(emulation.getProjectName());
|
||||
// extras.add(extraReq26);
|
||||
// SpdmDemandExtraReq extraReq27 = new SpdmDemandExtraReq();
|
||||
// extraReq27.setDemandId(uuid);
|
||||
// extraReq27.setPropertyName("projectModel");
|
||||
// extraReq27.setPropertyValue(emulation.getProjectModel());
|
||||
// extras.add(extraReq27);
|
||||
// SpdmDemandExtraReq extraReq28 = new SpdmDemandExtraReq();
|
||||
// extraReq28.setDemandId(uuid);
|
||||
// extraReq28.setPropertyName("projectType");
|
||||
// extraReq28.setPropertyValue(emulation.getProjectType());
|
||||
// extras.add(extraReq28);
|
||||
// SpdmDemandExtraReq extraReq31 = new SpdmDemandExtraReq();
|
||||
// extraReq31.setDemandId(uuid);
|
||||
// extraReq31.setPropertyName("stationNum");
|
||||
// extraReq31.setPropertyValue(emulation.getStationNum());
|
||||
// extras.add(extraReq31);
|
||||
// SpdmDemandExtraReq extraReq32 = new SpdmDemandExtraReq();
|
||||
// extraReq32.setDemandId(uuid);
|
||||
// extraReq32.setPropertyName("planStartTime");
|
||||
// extraReq32.setPropertyValue(emulation.getPlanStartTime());
|
||||
// extras.add(extraReq32);
|
||||
// SpdmDemandExtraReq extraReq33 = new SpdmDemandExtraReq();
|
||||
// extraReq33.setDemandId(uuid);
|
||||
// extraReq33.setPropertyName("requirementsTime");
|
||||
// extraReq33.setPropertyValue(emulation.getRequiredTime());
|
||||
// extras.add(extraReq33);
|
||||
// SpdmDemandExtraReq extraReq34 = new SpdmDemandExtraReq();
|
||||
// extraReq34.setDemandId(uuid);
|
||||
// extraReq34.setPropertyName("pausedTime");
|
||||
// extraReq34.setPropertyValue(emulation.getPausedTime());
|
||||
// extras.add(extraReq34);
|
||||
// SpdmDemandExtraReq extraReq35 = new SpdmDemandExtraReq();
|
||||
// extraReq35.setDemandId(uuid);
|
||||
// extraReq35.setPropertyName("performer");
|
||||
// extraReq35.setPropertyValue(emulation.getPerformer());
|
||||
// extras.add(extraReq35);
|
||||
// SpdmDemandExtraReq extraReq36 = new SpdmDemandExtraReq();
|
||||
// extraReq36.setDemandId(uuid);
|
||||
// extraReq36.setPropertyName("performerName");
|
||||
// extraReq36.setPropertyValue(emulation.getPerformerName());
|
||||
// extras.add(extraReq36);
|
||||
// SpdmDemandExtraReq extraReq37 = new SpdmDemandExtraReq();
|
||||
// extraReq37.setDemandId(uuid);
|
||||
// extraReq37.setPropertyName("verifier");
|
||||
// extraReq37.setPropertyValue(emulation.getVerifier());
|
||||
// extras.add(extraReq37);
|
||||
// SpdmDemandExtraReq extraReq39 = new SpdmDemandExtraReq();
|
||||
// extraReq39.setDemandId(uuid);
|
||||
// extraReq39.setPropertyName("workHourPlan");
|
||||
// extraReq39.setPropertyValue(emulation.getWorkHourPlan());
|
||||
// extras.add(extraReq39);
|
||||
// SpdmDemandExtraReq extraReq40 = new SpdmDemandExtraReq();
|
||||
// extraReq40.setDemandId(uuid);
|
||||
// extraReq40.setPropertyName("realWorkHour");
|
||||
// extraReq40.setPropertyValue(emulation.getRealWorkHour());
|
||||
// extras.add(extraReq40);
|
||||
// SpdmDemandExtraReq extraReq41 = new SpdmDemandExtraReq();
|
||||
// extraReq41.setDemandId(uuid);
|
||||
// extraReq41.setPropertyName("standardWorkHour");
|
||||
// extraReq41.setPropertyValue(emulation.getStandardWorkHour());
|
||||
// extras.add(extraReq41);
|
||||
// SpdmDemandExtraReq extraReq42 = new SpdmDemandExtraReq();
|
||||
// extraReq42.setDemandId(uuid);
|
||||
// extraReq42.setPropertyName("turnDownReason");
|
||||
// extraReq42.setPropertyValue(emulation.getTurnDownReason());
|
||||
// extras.add(extraReq42);
|
||||
// extras = extras.stream().filter(extra -> StringUtils.isNotBlank(extra.getPropertyValue())).toList();
|
||||
|
||||
// 需求的成员
|
||||
// 仿真负责人
|
||||
|
||||
// 当前用户也授予权限
|
||||
UpdatePermissionReq updatePermissionReq = new UpdatePermissionReq();
|
||||
updatePermissionReq.setUserId(jobNumber);
|
||||
updatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> userPermissions = new HashMap<>();
|
||||
userPermissions.put(jobNumber, FilePermissionEnum.ALL.getValue());
|
||||
updatePermissionReq.setUserPermissions(userPermissions);
|
||||
currentUpdatePermissionList.add(updatePermissionReq);
|
||||
String emulationPerformer = emulation.getEmulationPerformer();
|
||||
if (StringUtils.isNotBlank(emulationPerformer)) {
|
||||
SpdmDemandRelateMemberReq pMemberReq = new SpdmDemandRelateMemberReq();
|
||||
pMemberReq.setDemandId(uuid);
|
||||
pMemberReq.setType(0);
|
||||
String pUserId = emulationPerformer.split("-")[0];
|
||||
if (isConvertibleToLong(pUserId)) {
|
||||
pMemberReq.setUserId(Long.valueOf(pUserId));
|
||||
UpdatePermissionReq pUpdatePermissionReq = new UpdatePermissionReq();
|
||||
pUpdatePermissionReq.setUserId(pMemberReq.getUserId());
|
||||
pUpdatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> pUserPermissions = new HashMap<>();
|
||||
pUserPermissions.put(pMemberReq.getUserId(), FilePermissionEnum.ALL.getValue());
|
||||
pUpdatePermissionReq.setUserPermissions(pUserPermissions);
|
||||
currentUpdatePermissionList.add(pUpdatePermissionReq);
|
||||
}
|
||||
pMemberReq.setCreateTime(curDateStr);
|
||||
pMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(pMemberReq);
|
||||
}
|
||||
|
||||
// 仿真执行人
|
||||
String emulationExecutor = emulation.getEmulationExecutor();
|
||||
if (StringUtils.isNotBlank(emulationExecutor)) {
|
||||
SpdmDemandRelateMemberReq eMemberReq = new SpdmDemandRelateMemberReq();
|
||||
eMemberReq.setDemandId(uuid);
|
||||
eMemberReq.setType(1);
|
||||
String eUserId = emulationExecutor.split("-")[0];
|
||||
if (isConvertibleToLong(eUserId)) {
|
||||
eMemberReq.setUserId(Long.valueOf(eUserId));
|
||||
UpdatePermissionReq eUpdatePermissionReq = new UpdatePermissionReq();
|
||||
eUpdatePermissionReq.setUserId(eMemberReq.getUserId());
|
||||
eUpdatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> eUserPermissions = new HashMap<>();
|
||||
eUserPermissions.put(eMemberReq.getUserId(), FilePermissionEnum.ALL.getValue());
|
||||
eUpdatePermissionReq.setUserPermissions(eUserPermissions);
|
||||
currentUpdatePermissionList.add(eUpdatePermissionReq);
|
||||
}
|
||||
eMemberReq.setCreateTime(curDateStr);
|
||||
eMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(eMemberReq);
|
||||
}
|
||||
|
||||
// 3D负责人
|
||||
String threeDimensionalPerformer = emulation.getThreeDimensionalPerformer();
|
||||
if (StringUtils.isNotBlank(emulationExecutor)) {
|
||||
SpdmDemandRelateMemberReq tMemberReq = new SpdmDemandRelateMemberReq();
|
||||
tMemberReq.setDemandId(uuid);
|
||||
tMemberReq.setType(2);
|
||||
String tUserId = threeDimensionalPerformer.split("-")[0];
|
||||
if (isConvertibleToLong(tUserId)) {
|
||||
tMemberReq.setUserId(Long.valueOf(tUserId));
|
||||
}
|
||||
tMemberReq.setCreateTime(curDateStr);
|
||||
tMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(tMemberReq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BatchCreateDirItem batchCreateDirItem = new BatchCreateDirItem();
|
||||
DirNodeInfo dirNodeInfo = new DirNodeInfo();
|
||||
dirNodeInfo.setUuId(uuid);
|
||||
dirNodeInfo.setParentUuId(null);
|
||||
dirNodeInfo.setUuIdOwnType(NodeTypeEnum.DEMAND.getValue());
|
||||
dirNodeInfo.setDirName(spdmAddDemandReq.getDemandName());
|
||||
batchCreateDirItem.setParentDirNodeInfo(dirNodeInfo);
|
||||
createDirItemList.add(batchCreateDirItem);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
demandMapper.addDemand(spdmAddDemandReq, tenantId, jobNumber);
|
||||
demandMapper.addDemandMember(allMemberList);
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(extras)) {
|
||||
for (SpdmDemandExtraReq extra : extras) {
|
||||
extra.setCreateTime(curDateStr);
|
||||
extra.setCreator(jobNumber);
|
||||
}
|
||||
demandMapper.addDemandExtra(extras);
|
||||
demandMapper.addDemand(demandReq, tenantId, jobNumber);
|
||||
if (CollectionUtils.isNotEmpty(memberList)) {
|
||||
demandMapper.addDemandMember(memberList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("手动同步代办时有异常:{}", e.getMessage());
|
||||
log.error("异步保存需求[{}]数据异常: ", demandReq.getDemandCode(), e);
|
||||
}
|
||||
}
|
||||
// 批量创建文件夹
|
||||
BatchCreateDirReq batchCreateDirReq = new BatchCreateDirReq();
|
||||
batchCreateDirReq.setItems(createDirItemList);
|
||||
batchCreateDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue());
|
||||
log.info("手动同步待办创建需求时,调用批量创建文件夹的参数为:{}", batchCreateDirReq);
|
||||
SdmResponse response = dataFeignClient.batchCreateDir(batchCreateDirReq);
|
||||
log.info("手动同步代办创建需求时,调用批量创建文件夹的返回值为:{}", response);
|
||||
},projectTaskThreadPoolExecutor);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(currentUpdatePermissionList)) {
|
||||
/**
|
||||
* 执行批量操作:创建文件夹 + 更新权限
|
||||
*/
|
||||
private void executeBatchOperations(List<BatchCreateDirItem> createDirItemList,
|
||||
List<UpdatePermissionReq> updatePermissionList) {
|
||||
// 批量创建文件夹
|
||||
if (CollectionUtils.isNotEmpty(createDirItemList)) {
|
||||
BatchCreateDirReq batchCreateDirReq = new BatchCreateDirReq();
|
||||
batchCreateDirReq.setItems(createDirItemList);
|
||||
batchCreateDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue());
|
||||
log.info("手动同步待办创建文件夹参数: {}", batchCreateDirReq);
|
||||
SdmResponse dirCreateResp = dataFeignClient.batchCreateDir(batchCreateDirReq);
|
||||
log.info("手动同步待办创建文件夹响应: {}", dirCreateResp);
|
||||
}
|
||||
|
||||
// 批量更新权限(异步)
|
||||
if (CollectionUtils.isNotEmpty(updatePermissionList)) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
for (UpdatePermissionReq permissionReq : currentUpdatePermissionList) {
|
||||
// 更新文件权限
|
||||
for (UpdatePermissionReq permissionReq : updatePermissionList) {
|
||||
try {
|
||||
SdmResponse updatePermissionResponse = dataFeignClient.updatePermission(permissionReq);
|
||||
log.info("手动同步代办时,更新用户权限的返回值为:{}", updatePermissionResponse);
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
SdmResponse permissionResp = dataFeignClient.updatePermission(permissionReq);
|
||||
log.info("更新需求[{}]权限响应: {}", permissionReq.getUuid(), permissionResp);
|
||||
} catch (Exception e) {
|
||||
log.error("更新需求[{}]权限异常: ", permissionReq.getUuid(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
},projectTaskThreadPoolExecutor);
|
||||
}
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public SdmResponse getTodoList() {
|
||||
// 1. 缓存校验
|
||||
SdmResponse cacheCheckResponse = checkSyncCache();
|
||||
if (cacheCheckResponse != null) {
|
||||
return cacheCheckResponse;
|
||||
}
|
||||
|
||||
// 2. 查询项目节点:提前过滤无效数据
|
||||
List<SimulationNode> projectNodeList = queryProjectNodeList();
|
||||
if (CollectionUtils.isEmpty(projectNodeList)) {
|
||||
log.info("getTodoList中无有效项目节点数据");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<String> projectCodeList = projectNodeList.stream()
|
||||
.map(SimulationNode::getNodeCode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 3. 查询待办数据并过滤已同步数据
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList = queryAndFilterTodoList(projectCodeList);
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("本次无待同步的待办数据");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
// 4. 构建同步数据并执行批量操作
|
||||
return syncTodoData(projectNodeList, todoInfoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,7 +61,9 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
@@ -73,6 +75,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -148,6 +151,12 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
@Autowired
|
||||
private LyricVProjectStationPlanToDmService lyricVProjectStationPlanToDmService;
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Autowired
|
||||
@Qualifier("projectTaskThreadPoolExecutor")
|
||||
private Executor projectTaskThreadPoolExecutor;
|
||||
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
@@ -189,18 +198,16 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
Map<Long, Byte> userPermissions = new HashMap<>();
|
||||
userPermissions.put(userId, FilePermissionEnum.ALL.getValue());
|
||||
updatePermissionReq.setUserPermissions(userPermissions);
|
||||
log.info("dirItem目阶段时,更新用户权限的参数为:{}",updatePermissionReq);
|
||||
log.info("创建项目阶段时,更新用户权限的参数为:{}",updatePermissionReq);
|
||||
SdmResponse updatePermissionResponse = dataFeignClient.updatePermission(updatePermissionReq);
|
||||
log.info("dirItem目阶段时,更新用户权限的返回值为:{}",updatePermissionResponse);
|
||||
log.info("创建项目阶段时,更新用户权限的返回值为:{}",updatePermissionResponse);
|
||||
}
|
||||
for (SpdmProjectNodeEditReq addNode : addNodeList) {
|
||||
String projectSource = addNode.getProjectSource();
|
||||
String nodeType = addNode.getNodeType();
|
||||
if (SYNC_PROJECT_SOURCE.equals(projectSource) && NodeTypeEnum.PROJECT.getValue().equals(nodeType)) {
|
||||
// 同步待办信息
|
||||
getTodoListByProjectNum(addNode.getNodeCode(),addNodeList);
|
||||
// TODO 同步主计划信息
|
||||
// getMainPlanListByProjectId(addNode.getProjectId(),addNode.getUuid());
|
||||
getTodoListByProjectNum(addNode.getNodeCode(),addNodeList, addNode.getUuid(),addNode.getNodeName());
|
||||
}
|
||||
}
|
||||
return SdmResponse.success(addNodeList);
|
||||
@@ -442,7 +449,6 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
|
||||
|
||||
private List<SpdmProjectNodeEditReq> addNode(List<SpdmProjectNodeEditReq> addNodeList, List<TaskNodeTag> tagMap, Long tenantId, Long jobNumber) {
|
||||
Long currentUserId = ThreadLocalContext.getUserId();
|
||||
log.info("addNode参数为:{}", addNodeList);
|
||||
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
String nodeManagerList;
|
||||
@@ -450,7 +456,6 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
List<SpdmNodeExtraReq> extraList;
|
||||
List<SpdmNodeExtraReq> allExtraList = new ArrayList<>();
|
||||
List<SpdmProjectNodeEditReq> currentNodeList;
|
||||
|
||||
// 如果项目当前阶段下存在机台、工位的信息,则直接拉取到DM系统中
|
||||
Optional<SpdmProjectNodeEditReq> projectOptional = addNodeList.stream().filter(node -> NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())).findFirst();
|
||||
if (projectOptional.isPresent()) {
|
||||
@@ -591,7 +596,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
}
|
||||
|
||||
// 设置 当前节点所属项目根节点uuid
|
||||
// addNode.getPid()为空时,在dirItem目,ownRootNodeUuid就是addNode本身uuid
|
||||
// addNode.getPid()为空时,在创建项目,ownRootNodeUuid就是addNode本身uuid
|
||||
// addNode.getPid()不为空时,在创建阶段,ownRootNodeUuid就是入参的pid父节点
|
||||
addNode.setOwnRootNodeUuid(ObjectUtils.isEmpty(addNode.getPid()) ? addNode.getUuid() : addNode.getPid());
|
||||
addNode.setCreateTime(curDateStr);
|
||||
@@ -1247,9 +1252,9 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
createDirReq.setParentUuId(ObjectUtils.isNotEmpty(parentUuid) ? parentUuid : null);
|
||||
createDirReq.setDirName(dirName);
|
||||
createDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue());
|
||||
log.info("dirItem目阶段时,调用创建文件夹的参数为:{}", createDirReq);
|
||||
log.info("创建项目阶段时,调用创建文件夹的参数为:{}", createDirReq);
|
||||
SdmResponse response = dataClientFeignClient.createDir(createDirReq);
|
||||
log.info("dirItem目阶段时,调用创建文件夹的返回值为:{}", response);
|
||||
log.info("创建项目阶段时,调用创建文件夹的返回值为:{}", response);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -2182,7 +2187,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
return resp;
|
||||
}
|
||||
try {
|
||||
// dirItem目节点的文件夹
|
||||
// 创建项目节点的文件夹
|
||||
SdmResponse response = createDir(spdmProjectNodeEditReq.getUuid(), spdmProjectNodeEditReq.getNodeType(), null, spdmProjectNodeEditReq.getNodeName());
|
||||
if (ObjectUtils.isEmpty(response) || response.getCode() != ResultCode.SUCCESS.getCode()) {
|
||||
log.error("同步CID项目:{}时,创建文件夹失败,原因为:{}",req.getProjectId() + " " + req.getProjectName(),response.getMessage());
|
||||
@@ -2240,184 +2245,409 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
public SdmResponse getTodoListByProjectNum(String projectNum,List<SpdmProjectNodeEditReq> allNodeList) {
|
||||
log.info("同步代办时,项目号为:{}", projectNum);
|
||||
/**
|
||||
* 根据项目编号同步待办事项并创建需求
|
||||
*
|
||||
* @param projectNum 项目编号
|
||||
* @param allNodeList 所有项目节点列表
|
||||
* @param projectNodeId 项目节点ID
|
||||
* @param projectNodeName 项目节点名称
|
||||
* @return 同步结果响应
|
||||
*/
|
||||
public SdmResponse getTodoListByProjectNum(String projectNum,
|
||||
List<SpdmProjectNodeEditReq> allNodeList,
|
||||
String projectNodeId,
|
||||
String projectNodeName) {
|
||||
// 1. 入参校验
|
||||
log.info("开始同步待办事项,项目号:{}", projectNum);
|
||||
if (StringUtils.isBlank(projectNum)) {
|
||||
log.error("同步待办时,项目号不能为空");
|
||||
return SdmResponse.failed("同步待办时,项目号不能为空");
|
||||
String errorMsg = "同步待办时,项目号不能为空";
|
||||
log.error(errorMsg);
|
||||
return SdmResponse.failed(errorMsg);
|
||||
}
|
||||
// 查询
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList = lyricVTodoInfoService.lambdaQuery().eq(LyricVTodoEmulationInfoDM::getProject, projectNum)
|
||||
.list();
|
||||
// 过滤掉数据库中已经有的需求
|
||||
|
||||
if (StringUtils.isBlank(projectNodeId)) {
|
||||
String errorMsg = "同步待办时,项目节点ID不能为空";
|
||||
log.error(errorMsg);
|
||||
return SdmResponse.failed(errorMsg);
|
||||
}
|
||||
|
||||
// 2. 查询待办列表
|
||||
List<LyricVTodoEmulationInfoDM> todoInfoList = queryTodoListByProjectNum(projectNum);
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("未同步到待办");
|
||||
log.info("项目{}未查询到待办事项,无需同步", projectNum);
|
||||
return SdmResponse.success();
|
||||
}
|
||||
log.info("同步到{}条待办", todoInfoList.size());
|
||||
List<SpdmDemandVo> allDemandList = demandMapper.getAllList();
|
||||
log.info("allDemandList:{}", allDemandList);
|
||||
if (CollectionUtils.isNotEmpty(allDemandList)) {
|
||||
List<String> demandCodeList = allDemandList.stream().map(SpdmDemandVo::getDemandCode).toList();
|
||||
todoInfoList = todoInfoList.stream().filter(todoInfo -> !demandCodeList.contains(String.valueOf(todoInfo.getTodoId()))).toList();
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("本次同步到的待办都已经进行过同步");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
log.info("项目{}查询到{}条待办事项", projectNum, todoInfoList.size());
|
||||
|
||||
// 3. 过滤已同步的待办
|
||||
todoInfoList = filterSyncedTodoList(todoInfoList);
|
||||
if (CollectionUtils.isEmpty(todoInfoList)) {
|
||||
log.info("项目{}本次同步到的待办都已经进行过同步,无需处理", projectNum);
|
||||
return SdmResponse.success();
|
||||
}
|
||||
log.info("项目{}过滤后待同步的待办数量:{}", projectNum, todoInfoList.size());
|
||||
|
||||
// 4. 准备基础数据
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
Long jobNumber = ThreadLocalContext.getUserId();
|
||||
String uuid;
|
||||
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
List<BatchCreateDirItem> createDirItemList = new ArrayList<>();
|
||||
List<UpdatePermissionReq> currentUpdatePermissionList = new ArrayList<>();
|
||||
for (LyricVTodoEmulationInfoDM emulation : todoInfoList) {
|
||||
Long currentUserId = ThreadLocalContext.getUserId();
|
||||
String currentTimeStr = DATE_FORMATTER.format(new Date());
|
||||
|
||||
// 预构建节点映射,避免重复遍历
|
||||
Map<String, SpdmProjectNodeEditReq> projectNodeMap = buildProjectNodeMap(allNodeList);
|
||||
|
||||
// 5. 处理待办事项,构建创建需求所需数据
|
||||
SyncTodoProcessResult processResult = processTodoItems(
|
||||
todoInfoList, projectNodeMap, currentUserId, currentTimeStr, tenantId);
|
||||
|
||||
// 6. 批量创建文件夹
|
||||
SdmResponse dirCreateResponse = batchCreateDemandDirs(
|
||||
processResult.getDemandDirNodeList(), projectNodeId, projectNodeName);
|
||||
if (!dirCreateResponse.isSuccess()) {
|
||||
log.error("项目{}批量创建需求文件夹失败:{}", projectNum, dirCreateResponse.getMessage());
|
||||
return SdmResponse.failed("同步待办失败:创建文件夹失败");
|
||||
}
|
||||
|
||||
// 7. 批量更新权限(异步)
|
||||
updateDemandPermissionsAsync(processResult.getPermissionReqList());
|
||||
|
||||
log.info("项目{}待办事项同步完成,共处理{}条待办", projectNum, todoInfoList.size());
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定项目的待办列表
|
||||
*/
|
||||
private List<LyricVTodoEmulationInfoDM> queryTodoListByProjectNum(String projectNum) {
|
||||
try {
|
||||
return lyricVTodoInfoService.lambdaQuery()
|
||||
.eq(LyricVTodoEmulationInfoDM::getProject, projectNum)
|
||||
.list();
|
||||
} catch (Exception e) {
|
||||
log.error("查询项目{}待办列表失败", projectNum, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤已经同步过的待办事项
|
||||
*/
|
||||
private List<LyricVTodoEmulationInfoDM> filterSyncedTodoList(List<LyricVTodoEmulationInfoDM> todoInfoList) {
|
||||
List<SpdmDemandVo> allDemandList = demandMapper.getAllList();
|
||||
log.info("已存在的需求列表数量:{}", CollectionUtils.size(allDemandList));
|
||||
|
||||
if (CollectionUtils.isEmpty(allDemandList)) {
|
||||
return todoInfoList;
|
||||
}
|
||||
|
||||
// 提取已存在的需求编码
|
||||
Set<String> existingDemandCodeSet = allDemandList.stream()
|
||||
.map(SpdmDemandVo::getDemandCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 过滤已同步的待办
|
||||
return todoInfoList.stream()
|
||||
.filter(todoInfo -> {
|
||||
String todoIdStr = String.valueOf(todoInfo.getTodoId());
|
||||
return !existingDemandCodeSet.contains(todoIdStr);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建项目节点映射表,避免重复遍历
|
||||
*/
|
||||
private Map<String, SpdmProjectNodeEditReq> buildProjectNodeMap(List<SpdmProjectNodeEditReq> allNodeList) {
|
||||
Map<String, SpdmProjectNodeEditReq> nodeMap = new HashMap<>();
|
||||
|
||||
if (CollectionUtils.isEmpty(allNodeList)) {
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
// 按节点类型+节点编码构建唯一键
|
||||
for (SpdmProjectNodeEditReq node : allNodeList) {
|
||||
String key = node.getNodeType() + "_" + node.getNodeCode();
|
||||
nodeMap.put(key, node);
|
||||
}
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理待办事项,构建创建需求所需的各类数据
|
||||
*/
|
||||
private SyncTodoProcessResult processTodoItems(List<LyricVTodoEmulationInfoDM> todoInfoList,
|
||||
Map<String, SpdmProjectNodeEditReq> projectNodeMap,
|
||||
Long currentUserId,
|
||||
String currentTimeStr,
|
||||
Long tenantId) {
|
||||
List<DirNodeInfo> demandDirNodeList = new ArrayList<>();
|
||||
List<UpdatePermissionReq> permissionReqList = new ArrayList<>();
|
||||
|
||||
for (LyricVTodoEmulationInfoDM todoItem : todoInfoList) {
|
||||
try {
|
||||
List<SpdmDemandExtraReq> extras = new ArrayList<>();
|
||||
List<SpdmDemandRelateMemberReq> allMemberList = new ArrayList<>();
|
||||
// 需求的基础属性
|
||||
SpdmAddDemandReq spdmAddDemandReq = new SpdmAddDemandReq();
|
||||
uuid = RandomUtil.generateString(32);
|
||||
spdmAddDemandReq.setUuid(uuid);
|
||||
spdmAddDemandReq.setDemandName(emulation.getSubject());
|
||||
if (ObjectUtils.isNotEmpty(emulation.getTodoId())) {
|
||||
spdmAddDemandReq.setDemandCode(String.valueOf(emulation.getTodoId()));
|
||||
}
|
||||
spdmAddDemandReq.setDemandType(emulation.getEmulationType());
|
||||
spdmAddDemandReq.setSimType(emulation.getRelevanceTask());
|
||||
spdmAddDemandReq.setDemandStatus("0");
|
||||
spdmAddDemandReq.setAchieveStatus("0");
|
||||
spdmAddDemandReq.setProgress(0);
|
||||
spdmAddDemandReq.setBeginTime(emulation.getPlanStartTime());
|
||||
spdmAddDemandReq.setEndTime(emulation.getClosedTime());
|
||||
String projectNode = emulation.getProject();
|
||||
String phaseNode = emulation.getProjectStage();
|
||||
String workspaceNode = emulation.getStationNum();
|
||||
Optional<SpdmProjectNodeEditReq> projectOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(projectNode)
|
||||
&& NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())).findFirst();
|
||||
Optional<SpdmProjectNodeEditReq> phaseOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(phaseNode)
|
||||
&& NodeTypeEnum.PHASE.getValue().equals(node.getNodeType())).findFirst();
|
||||
Optional<SpdmProjectNodeEditReq> workspaceOptional = allNodeList.stream().filter(node -> node.getNodeCode().equals(workspaceNode)
|
||||
&& NodeTypeEnum.WORKSPACE.getValue().equals(node.getNodeType())).findFirst();
|
||||
// 转换为project的uuid
|
||||
projectOptional.ifPresent(simulationNode -> spdmAddDemandReq.setProjectId(simulationNode.getUuid()));
|
||||
phaseOptional.ifPresent(simulationNode -> spdmAddDemandReq.setPhaseId(simulationNode.getUuid()));
|
||||
workspaceOptional.ifPresent(simulationNode -> spdmAddDemandReq.setNodeId(simulationNode.getUuid()));
|
||||
spdmAddDemandReq.setCreateTime(curDateStr);
|
||||
spdmAddDemandReq.setDemandSource(SYNC_PROJECT_SOURCE);
|
||||
// 需求的成员
|
||||
// 当前用户也授予权限
|
||||
UpdatePermissionReq updatePermissionReq = new UpdatePermissionReq();
|
||||
updatePermissionReq.setUserId(jobNumber);
|
||||
updatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> userPermissions = new HashMap<>();
|
||||
userPermissions.put(jobNumber, FilePermissionEnum.ALL.getValue());
|
||||
updatePermissionReq.setUserPermissions(userPermissions);
|
||||
currentUpdatePermissionList.add(updatePermissionReq);
|
||||
// 仿真负责人
|
||||
String emulationPerformer = emulation.getEmulationPerformer();
|
||||
if (StringUtils.isNotBlank(emulationPerformer)) {
|
||||
SpdmDemandRelateMemberReq pMemberReq = new SpdmDemandRelateMemberReq();
|
||||
pMemberReq.setDemandId(uuid);
|
||||
pMemberReq.setType(0);
|
||||
String pUserId = emulationPerformer.split("-")[0];
|
||||
if (isConvertibleToLong(pUserId)) {
|
||||
pMemberReq.setUserId(Long.valueOf(pUserId));
|
||||
UpdatePermissionReq pUpdatePermissionReq = new UpdatePermissionReq();
|
||||
pUpdatePermissionReq.setUserId(pMemberReq.getUserId());
|
||||
pUpdatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> pUserPermissions = new HashMap<>();
|
||||
pUserPermissions.put(pMemberReq.getUserId(), FilePermissionEnum.ALL.getValue());
|
||||
pUpdatePermissionReq.setUserPermissions(pUserPermissions);
|
||||
currentUpdatePermissionList.add(pUpdatePermissionReq);
|
||||
}
|
||||
pMemberReq.setCreateTime(curDateStr);
|
||||
pMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(pMemberReq);
|
||||
}
|
||||
String demandUuid = RandomUtil.generateString(32);
|
||||
|
||||
// 仿真执行人
|
||||
String emulationExecutor = emulation.getEmulationExecutor();
|
||||
if (StringUtils.isNotBlank(emulationExecutor)) {
|
||||
SpdmDemandRelateMemberReq eMemberReq = new SpdmDemandRelateMemberReq();
|
||||
eMemberReq.setDemandId(uuid);
|
||||
eMemberReq.setType(1);
|
||||
String eUserId = emulationExecutor.split("-")[0];
|
||||
if (isConvertibleToLong(eUserId)) {
|
||||
eMemberReq.setUserId(Long.valueOf(eUserId));
|
||||
UpdatePermissionReq eUpdatePermissionReq = new UpdatePermissionReq();
|
||||
eUpdatePermissionReq.setUserId(eMemberReq.getUserId());
|
||||
eUpdatePermissionReq.setUuid(uuid);
|
||||
Map<Long, Byte> eUserPermissions = new HashMap<>();
|
||||
eUserPermissions.put(eMemberReq.getUserId(), FilePermissionEnum.ALL.getValue());
|
||||
eUpdatePermissionReq.setUserPermissions(eUserPermissions);
|
||||
currentUpdatePermissionList.add(eUpdatePermissionReq);
|
||||
}
|
||||
eMemberReq.setCreateTime(curDateStr);
|
||||
eMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(eMemberReq);
|
||||
}
|
||||
// 1. 构建基础需求信息
|
||||
SpdmAddDemandReq demandAddReq = buildDemandAddReq(todoItem, demandUuid, projectNodeMap, currentTimeStr);
|
||||
|
||||
// 3D负责人
|
||||
String threeDimensionalPerformer = emulation.getThreeDimensionalPerformer();
|
||||
if (StringUtils.isNotBlank(emulationExecutor)) {
|
||||
SpdmDemandRelateMemberReq tMemberReq = new SpdmDemandRelateMemberReq();
|
||||
tMemberReq.setDemandId(uuid);
|
||||
tMemberReq.setType(2);
|
||||
String tUserId = threeDimensionalPerformer.split("-")[0];
|
||||
if (isConvertibleToLong(tUserId)) {
|
||||
tMemberReq.setUserId(Long.valueOf(tUserId));
|
||||
}
|
||||
tMemberReq.setCreateTime(curDateStr);
|
||||
tMemberReq.setCreator(jobNumber);
|
||||
allMemberList.add(tMemberReq);
|
||||
}
|
||||
// 2. 构建成员信息和权限信息
|
||||
List<SpdmDemandRelateMemberReq> memberList = buildDemandMemberList(
|
||||
todoItem, demandUuid, currentUserId, currentTimeStr, permissionReqList);
|
||||
|
||||
// 3. 构建文件夹节点信息
|
||||
DirNodeInfo demandDirNode = buildDemandDirNode(demandUuid, todoItem.getSubject(), projectNodeMap.get(NodeTypeEnum.PROJECT.getValue() + "_" + todoItem.getProject()).getUuid());
|
||||
demandDirNodeList.add(demandDirNode);
|
||||
|
||||
// 4. 异步保存需求和成员信息
|
||||
saveDemandAndMembersAsync(demandAddReq, memberList, tenantId, currentUserId);
|
||||
|
||||
BatchCreateDirItem batchCreateDirItem = new BatchCreateDirItem();
|
||||
DirNodeInfo dirNodeInfo = new DirNodeInfo();
|
||||
dirNodeInfo.setUuId(uuid);
|
||||
dirNodeInfo.setParentUuId(null);
|
||||
dirNodeInfo.setUuIdOwnType(NodeTypeEnum.DEMAND.getValue());
|
||||
dirNodeInfo.setDirName(spdmAddDemandReq.getDemandName());
|
||||
batchCreateDirItem.setParentDirNodeInfo(dirNodeInfo);
|
||||
createDirItemList.add(batchCreateDirItem);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
demandMapper.addDemand(spdmAddDemandReq, tenantId, jobNumber);
|
||||
demandMapper.addDemandMember(allMemberList);
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(extras)) {
|
||||
for (SpdmDemandExtraReq extra : extras) {
|
||||
extra.setCreateTime(curDateStr);
|
||||
extra.setCreator(jobNumber);
|
||||
}
|
||||
demandMapper.addDemandExtra(extras);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("同步代办时有异常:{}", e.getMessage());
|
||||
log.error("处理待办事项失败,待办ID:{},错误信息:{}", todoItem.getTodoId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
// 批量创建文件夹
|
||||
BatchCreateDirReq batchCreateDirReq = new BatchCreateDirReq();
|
||||
batchCreateDirReq.setItems(createDirItemList);
|
||||
batchCreateDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue());
|
||||
log.info("同步待办创建需求时,调用批量创建文件夹的参数为:{}", batchCreateDirReq);
|
||||
SdmResponse response = dataFeignClient.batchCreateDir(batchCreateDirReq);
|
||||
log.info("同步代办创建需求时,调用批量创建文件夹的返回值为:{}", response);
|
||||
// TODO 更新用户权限也需要批量接口来优化
|
||||
if (CollectionUtils.isNotEmpty(currentUpdatePermissionList)) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
for (UpdatePermissionReq permissionReq : currentUpdatePermissionList) {
|
||||
// 更新文件权限
|
||||
try {
|
||||
SdmResponse updatePermissionResponse = dataFeignClient.updatePermission(permissionReq);
|
||||
log.info("同步需求时,更新用户权限的返回值为:{}", updatePermissionResponse);
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return new SyncTodoProcessResult(demandDirNodeList, permissionReqList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建新增需求的基础信息
|
||||
*/
|
||||
private SpdmAddDemandReq buildDemandAddReq(LyricVTodoEmulationInfoDM todoItem,
|
||||
String demandUuid,
|
||||
Map<String, SpdmProjectNodeEditReq> projectNodeMap,
|
||||
String currentTimeStr) {
|
||||
SpdmAddDemandReq demandAddReq = new SpdmAddDemandReq();
|
||||
|
||||
// 基础属性
|
||||
demandAddReq.setUuid(demandUuid);
|
||||
demandAddReq.setDemandName(todoItem.getSubject());
|
||||
demandAddReq.setDemandCode(ObjectUtils.isNotEmpty(todoItem.getTodoId()) ? String.valueOf(todoItem.getTodoId()) : null);
|
||||
demandAddReq.setDemandType(todoItem.getEmulationType());
|
||||
demandAddReq.setSimType(todoItem.getRelevanceTask());
|
||||
demandAddReq.setDemandStatus("0");
|
||||
demandAddReq.setAchieveStatus("0");
|
||||
demandAddReq.setProgress(0);
|
||||
demandAddReq.setBeginTime(todoItem.getPlanStartTime());
|
||||
demandAddReq.setEndTime(todoItem.getClosedTime());
|
||||
demandAddReq.setCreateTime(currentTimeStr);
|
||||
demandAddReq.setDemandSource(SYNC_PROJECT_SOURCE);
|
||||
|
||||
// 节点信息
|
||||
demandAddReq.setProjectId(getNodeUuid(projectNodeMap, NodeTypeEnum.PROJECT.getValue(), todoItem.getProject()));
|
||||
demandAddReq.setPhaseId(getNodeUuid(projectNodeMap, NodeTypeEnum.PHASE.getValue(), todoItem.getProjectStage()));
|
||||
demandAddReq.setNodeId(getNodeUuid(projectNodeMap, NodeTypeEnum.WORKSPACE.getValue(), todoItem.getStationNum()));
|
||||
|
||||
return demandAddReq;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点UUID
|
||||
*/
|
||||
private String getNodeUuid(Map<String, SpdmProjectNodeEditReq> projectNodeMap, String nodeType, String nodeCode) {
|
||||
if (StringUtils.isBlank(nodeType) || StringUtils.isBlank(nodeCode)) {
|
||||
return null;
|
||||
}
|
||||
SpdmProjectNodeEditReq node = projectNodeMap.get(nodeType + "_" + nodeCode);
|
||||
return node != null ? node.getUuid() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建需求成员列表,并同步构建权限请求
|
||||
*/
|
||||
private List<SpdmDemandRelateMemberReq> buildDemandMemberList(LyricVTodoEmulationInfoDM todoItem,
|
||||
String demandUuid,
|
||||
Long currentUserId,
|
||||
String currentTimeStr,
|
||||
List<UpdatePermissionReq> permissionReqList) {
|
||||
List<SpdmDemandRelateMemberReq> memberList = new ArrayList<>();
|
||||
|
||||
// 添加当前用户权限
|
||||
addUserPermission(permissionReqList, demandUuid, currentUserId);
|
||||
|
||||
// 仿真负责人
|
||||
addDemandMember(todoItem.getEmulationPerformer(), 0, demandUuid, currentUserId, currentTimeStr, memberList, permissionReqList);
|
||||
|
||||
// 仿真执行人
|
||||
addDemandMember(todoItem.getEmulationExecutor(), 1, demandUuid, currentUserId, currentTimeStr, memberList, permissionReqList);
|
||||
|
||||
// 3D负责人(修复原代码的bug:判断条件错误)
|
||||
addDemandMember(todoItem.getThreeDimensionalPerformer(), 2, demandUuid, currentUserId, currentTimeStr, memberList, permissionReqList);
|
||||
|
||||
return memberList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加需求成员
|
||||
*/
|
||||
private void addDemandMember(String userInfo, int memberType, String demandUuid,
|
||||
Long currentUserId, String currentTimeStr,
|
||||
List<SpdmDemandRelateMemberReq> memberList,
|
||||
List<UpdatePermissionReq> permissionReqList) {
|
||||
if (StringUtils.isBlank(userInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String userIdStr = userInfo.split("-")[0];
|
||||
if (!isConvertibleToLong(userIdStr)) {
|
||||
log.warn("用户ID转换失败,原始数据:{}", userInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Long userId = Long.valueOf(userIdStr);
|
||||
|
||||
// 构建成员信息
|
||||
SpdmDemandRelateMemberReq memberReq = new SpdmDemandRelateMemberReq();
|
||||
memberReq.setDemandId(demandUuid);
|
||||
memberReq.setType(memberType);
|
||||
memberReq.setUserId(userId);
|
||||
memberReq.setCreateTime(currentTimeStr);
|
||||
memberReq.setCreator(currentUserId);
|
||||
memberList.add(memberReq);
|
||||
|
||||
// 添加权限
|
||||
addUserPermission(permissionReqList, demandUuid, userId);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("添加需求成员失败,用户信息:{},成员类型:{}", userInfo, memberType, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户权限
|
||||
*/
|
||||
private void addUserPermission(List<UpdatePermissionReq> permissionReqList,
|
||||
String demandUuid,
|
||||
Long userId) {
|
||||
UpdatePermissionReq permissionReq = new UpdatePermissionReq();
|
||||
permissionReq.setUserId(userId);
|
||||
permissionReq.setUuid(demandUuid);
|
||||
|
||||
Map<Long, Byte> userPermissions = new HashMap<>();
|
||||
userPermissions.put(userId, FilePermissionEnum.ALL.getValue());
|
||||
permissionReq.setUserPermissions(userPermissions);
|
||||
|
||||
permissionReqList.add(permissionReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建需求文件夹节点信息
|
||||
*/
|
||||
private DirNodeInfo buildDemandDirNode(String demandUuid, String demandName, String parentNodeId) {
|
||||
DirNodeInfo dirNodeInfo = new DirNodeInfo();
|
||||
dirNodeInfo.setUuId(demandUuid);
|
||||
dirNodeInfo.setParentUuId(parentNodeId);
|
||||
dirNodeInfo.setUuIdOwnType(NodeTypeEnum.DEMAND.getValue());
|
||||
dirNodeInfo.setDirName(demandName);
|
||||
return dirNodeInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步保存需求和成员信息
|
||||
*/
|
||||
private void saveDemandAndMembersAsync(SpdmAddDemandReq demandAddReq,
|
||||
List<SpdmDemandRelateMemberReq> memberList,
|
||||
Long tenantId,
|
||||
Long currentUserId) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
demandMapper.addDemand(demandAddReq, tenantId, currentUserId);
|
||||
if (CollectionUtils.isNotEmpty(memberList)) {
|
||||
demandMapper.addDemandMember(memberList);
|
||||
}
|
||||
log.info("异步保存需求成功,需求ID:{}", demandAddReq.getUuid());
|
||||
} catch (Exception e) {
|
||||
log.error("异步保存需求失败,需求ID:{}", demandAddReq.getUuid(), e);
|
||||
}
|
||||
}, projectTaskThreadPoolExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建需求文件夹
|
||||
*/
|
||||
private SdmResponse batchCreateDemandDirs(List<DirNodeInfo> demandDirNodeList,
|
||||
String projectNodeId,
|
||||
String projectNodeName) {
|
||||
if (CollectionUtils.isEmpty(demandDirNodeList)) {
|
||||
log.info("无需求文件夹需要创建");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
// 构建项目目录节点
|
||||
DirNodeInfo projectDirNodeInfo = new DirNodeInfo();
|
||||
projectDirNodeInfo.setUuId(projectNodeId);
|
||||
projectDirNodeInfo.setParentUuId(null);
|
||||
projectDirNodeInfo.setUuIdOwnType(NodeTypeEnum.PROJECT.getValue());
|
||||
projectDirNodeInfo.setDirName(projectNodeName);
|
||||
|
||||
// 构建批量创建请求
|
||||
BatchCreateDirItem demandCreateDirItem = new BatchCreateDirItem();
|
||||
demandCreateDirItem.setParentDirNodeInfo(projectDirNodeInfo);
|
||||
demandCreateDirItem.setChildDirNodeInfos(demandDirNodeList);
|
||||
|
||||
BatchCreateDirReq batchCreateDirReq = new BatchCreateDirReq();
|
||||
batchCreateDirReq.setItems(Collections.singletonList(demandCreateDirItem));
|
||||
batchCreateDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue());
|
||||
|
||||
log.info("批量创建需求文件夹请求参数:{}", batchCreateDirReq);
|
||||
try {
|
||||
SdmResponse response = dataFeignClient.batchCreateDir(batchCreateDirReq);
|
||||
log.info("批量创建需求文件夹响应:{}", response);
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("调用批量创建文件夹接口失败", e);
|
||||
return SdmResponse.failed("创建文件夹失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步更新需求权限
|
||||
*/
|
||||
private void updateDemandPermissionsAsync(List<UpdatePermissionReq> permissionReqList) {
|
||||
if (CollectionUtils.isEmpty(permissionReqList)) {
|
||||
log.info("无权限需要更新");
|
||||
return;
|
||||
}
|
||||
|
||||
CompletableFuture.runAsync(() -> {
|
||||
log.info("开始异步更新{}条权限记录", permissionReqList.size());
|
||||
for (UpdatePermissionReq permissionReq : permissionReqList) {
|
||||
try {
|
||||
SdmResponse updateResponse = dataFeignClient.updatePermission(permissionReq);
|
||||
if (!updateResponse.isSuccess()) {
|
||||
log.warn("更新权限失败,需求ID:{},用户ID:{},响应:{}",
|
||||
permissionReq.getUuid(), permissionReq.getUserId(), updateResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("更新权限异常,需求ID:{},用户ID:{}",
|
||||
permissionReq.getUuid(), permissionReq.getUserId(), e);
|
||||
}
|
||||
}
|
||||
log.info("异步更新权限完成");
|
||||
}, projectTaskThreadPoolExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部数据传输对象:待办处理结果
|
||||
*/
|
||||
private static class SyncTodoProcessResult {
|
||||
private final List<DirNodeInfo> demandDirNodeList;
|
||||
private final List<UpdatePermissionReq> permissionReqList;
|
||||
|
||||
public SyncTodoProcessResult(List<DirNodeInfo> demandDirNodeList,
|
||||
List<UpdatePermissionReq> permissionReqList) {
|
||||
this.demandDirNodeList = demandDirNodeList;
|
||||
this.permissionReqList = permissionReqList;
|
||||
}
|
||||
|
||||
public List<DirNodeInfo> getDemandDirNodeList() {
|
||||
return demandDirNodeList;
|
||||
}
|
||||
|
||||
public List<UpdatePermissionReq> getPermissionReqList() {
|
||||
return permissionReqList;
|
||||
}
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
public SdmResponse getMainPlanListByProjectId(Integer projectId, String projectUuid) {
|
||||
|
||||
Reference in New Issue
Block a user