fix[project]: 同步待办时,下载待办的报告文件

This commit is contained in:
2026-03-23 20:09:49 +08:00
parent 6418c89d3a
commit e1771f81b6
15 changed files with 512 additions and 110 deletions

View File

@@ -225,5 +225,11 @@ public class SimulationLyricNodeController {
return lyricInternalService.acceptTodoInfo(req);
}
@GetMapping("/manuallySupplementTodoReport")
@Operation(summary = "手动补充待办报告文件", description = "手动补充待办报告文件")
public SdmResponse manuallySupplementTodoReport(@RequestParam(value = "taskId", required = false) String taskId) {
return lyricInternalService.manuallySupplementTodoReport(taskId);
}
}

View File

@@ -6,11 +6,13 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
@@ -88,4 +90,9 @@ public class SimulationDemand implements Serializable {
@TableField("description")
private String description;
@Schema(description= "关联的待办的结果文件路径")
@TableField(exist = false)
private List<String> reportFileUrlList;
}

View File

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -221,7 +223,7 @@ public class SimulationTask implements Serializable {
@Schema(description= "关联的待办的结果文件路径")
@TableField(exist = false)
private String reportFileUrl;
private List<String> reportFileUrlList;
}

View File

@@ -1,8 +1,10 @@
package com.sdm.project.model.req;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sdm.common.entity.pojo.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -154,4 +156,7 @@ public class SpdmAddDemandReq extends BaseEntity {
*/
private Boolean isLyric=false;
@Schema(description= "关联的待办的结果文件路径")
private List<String> reportFileUrlList;
}

View File

@@ -1,10 +1,12 @@
package com.sdm.project.model.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sdm.common.entity.pojo.BaseEntity;
import com.sdm.common.entity.resp.system.CIDUserResp;
import com.sdm.project.model.req.SpdmDemandExtraReq;
import com.sdm.project.model.vo.SpdmDemandMemberVo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -192,4 +194,7 @@ public class SpdmDemandVo extends BaseEntity {
*/
private String produceLine;
@Schema(description= "关联的待办的结果文件路径")
private List<String> reportFileUrlList;
}

View File

@@ -63,4 +63,6 @@ public interface ILyricInternalService {
SdmResponse acceptTodoInfo(SpdmAcceptTodoInfoReq req);
SdmResponse manuallySupplementTodoReport(String taskId);
}

View File

@@ -24,6 +24,6 @@ public interface ISimulationTaskService extends IService<SimulationTask> {
SdmResponse editTaskForData(TaskEditNodeReq req);
void batchCreateTaskFromDemand(List<SimulationDemand> demandList);
void batchCreateTaskFromDemand(List<SimulationDemand> demandList,Boolean isDownloadFlag);
}

View File

@@ -342,7 +342,7 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
if (req.getIsLyric()) {
SimulationDemand demand = new SimulationDemand();
BeanUtils.copyProperties(req, demand);
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand));
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand),false);
}
return SdmResponse.success(req.getUuid());
@@ -1821,7 +1821,7 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
if (req.getIsLyric()) {
SimulationDemand demand = new SimulationDemand();
BeanUtils.copyProperties(req, demand);
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand));
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand),false);
}
return SdmResponse.success(req.getUuid());

View File

@@ -1,5 +1,6 @@
package com.sdm.project.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@@ -7,10 +8,7 @@ import com.sdm.common.common.ResultCode;
import com.sdm.common.common.SdmResponse;
import com.sdm.common.common.ThreadLocalContext;
import com.sdm.common.constants.LyricParamConstants;
import com.sdm.common.entity.enums.AttachFileTypeEnum;
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.enums.*;
import com.sdm.common.entity.req.data.*;
import com.sdm.common.entity.req.lyric.SpdmAcceptTodoInfoReq;
import com.sdm.common.entity.req.project.SpdmNodeListReq;
@@ -49,6 +47,7 @@ import com.sdm.project.dao.SimulationTaskMapper;
import com.sdm.project.model.bo.TaskNodeTag;
import com.sdm.project.model.entity.SimulationDemand;
import com.sdm.project.model.entity.SimulationNode;
import com.sdm.project.model.entity.SimulationTask;
import com.sdm.project.model.req.*;
import com.sdm.project.model.req.ep.EpProjectQueryReq;
import com.sdm.project.model.req.ep.EpSyncPhaseReq;
@@ -68,6 +67,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@@ -91,6 +91,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static com.sdm.project.service.impl.NodeServiceImpl.SYNC_PROJECT_SOURCE;
import static com.sdm.project.service.impl.SimulationTaskServiceImpl.REPORT_PATH_PREFIX;
@Service
@Slf4j
@@ -196,6 +197,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
@Autowired
private LyricVProjectStationExcepTionToDMService lyricVProjectStationExcepTionToDMService;
@Autowired
private LyricVAttachmentConfigService lyricVAttachmentConfigService;
@Autowired
private SimulationTaskExtraMapper simulationTaskExtraMapper;
@@ -376,6 +380,43 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
return filterTodoList;
}
/**
* 将列表中的字符串按逗号拆分,合并后去重
* @param sourceList 原始字符串列表
* @return 拆分去重后的新列表
*/
public static List<String> splitAndDistinct(List<String> sourceList) {
// 1. 判空处理,避免空指针
if (sourceList == null || sourceList.isEmpty()) {
return new ArrayList<>();
}
// 2. 使用LinkedHashSet保证去重且保留插入顺序
Set<String> tempSet = new LinkedHashSet<>();
// 3. 遍历原始列表拆分每个字符串并添加到Set中
for (String str : sourceList) {
// 跳过空字符串,避免拆分出空元素
if (str == null || str.trim().isEmpty()) {
continue;
}
// 按逗号拆分字符串
String[] splitArray = str.split(",");
// 遍历拆分后的数组添加到Set自动去重
for (String item : splitArray) {
// 去除首尾空格如果需要的话不需要可删除trim()
String cleanItem = item.trim();
// 跳过拆分后为空的元素
if (!cleanItem.isEmpty()) {
tempSet.add(cleanItem);
}
}
}
// 4. 将Set转换为List返回
return new ArrayList<>(tempSet);
}
/**
* 核心同步逻辑:构建数据并执行批量操作
*/
@@ -414,6 +455,34 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
List<CIDUserResp> userList = pageDataRespSdmResponse.getData().getData();
usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId));
}
// 构建一个需求todoId到resultFileId的映射
Map<Long,String> resultFileIdMap = todoInfoList.stream().collect(Collectors.toMap(LyricVTodoEmulationInfoDM::getTodoId,LyricVTodoEmulationInfoDM::getResultFileId,(oldValue, newValue) -> oldValue));
// 构建一个resultFileId到filePath的映射
Map<Integer,String> filePathMap = new HashMap<>();
// 查询filePath
List<String> resultFileIdStrList = todoInfoList.stream().map(LyricVTodoEmulationInfoDM::getResultFileId).filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdStrList)) {
resultFileIdStrList = splitAndDistinct(resultFileIdStrList);
List<Integer> resultFileIdList = resultFileIdStrList.stream()
.map(str -> {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("跳过无效数字:" + str);
return null; // 转换失败返回null
}
})
.filter(Objects::nonNull) // 过滤掉null值
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdList)) {
List<LyricVAttachmentConfigToDM> attachmentConfigToDMList = lyricVAttachmentConfigService.lambdaQuery().in(LyricVAttachmentConfigToDM::getId, resultFileIdList)
.list();
if (CollectionUtils.isNotEmpty(attachmentConfigToDMList)) {
filePathMap = attachmentConfigToDMList.stream().collect(Collectors.toMap(LyricVAttachmentConfigToDM::getId,LyricVAttachmentConfigToDM::getFilePath,(oldValue, newValue) -> oldValue));
}
}
}
for (SimulationNode projectNode : projectNodeList) {
String projectCode = projectNode.getNodeCode();
@@ -459,9 +528,34 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
executeBatchOperations(createDirItemList, updatePermissionList);
if (CollectionUtils.isNotEmpty(demandToCreateTaskList)) {
simulationTaskService.batchCreateTaskFromDemand(demandToCreateTaskList);
for (SimulationDemand simulationDemand : demandToCreateTaskList) {
List<String> reportFileUrlList = new ArrayList<>();
String demandCode = simulationDemand.getDemandCode();
String reportFileUrl = null;
if (StringUtils.isNotBlank(demandCode) && isConvertibleToLong(demandCode)) {
// resultFileId可能有多个逗号隔开
String resultFileIdStr = resultFileIdMap.get(Long.valueOf(demandCode));
if (StringUtils.isNotBlank(resultFileIdStr)) {
try {
for (String resultFileId : Arrays.stream(resultFileIdStr.split(",")).toList()) {
reportFileUrl = filePathMap.get(Integer.parseInt(resultFileId));
if (StringUtils.isBlank(reportFileUrl)) {
continue;
}
reportFileUrlList.add(reportFileUrl);
}
} catch (NumberFormatException e) {
log.error("跳过无效数字:{}",resultFileIdStr);
}
}
}
if (CollectionUtils.isEmpty(reportFileUrlList)) {
continue;
}
simulationDemand.setReportFileUrlList(reportFileUrlList);
}
simulationTaskService.batchCreateTaskFromDemand(demandToCreateTaskList,true);
}
return SdmResponse.success();
} catch (Exception e) {
log.error("syncTodoData 未知 error: {}", e.getMessage());
@@ -4147,11 +4241,170 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
SimulationDemand demand = new SimulationDemand();
BeanUtils.copyProperties(req, demand);
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand));
simulationTaskService.batchCreateTaskFromDemand(Collections.singletonList(demand),false);
return SdmResponse.success(req.getUuid());
}
@Override
public SdmResponse manuallySupplementTodoReport(String taskId) {
List<SimulationTask> taskList;
if (StringUtils.isNotBlank(taskId)) {
// 任务id不为空单个测试
taskList = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, taskId).isNotNull(SimulationTask::getDemandId).list();
}else {
// 直接同步全部待办的报告到关联的任务文件夹下
taskList = simulationTaskService.lambdaQuery().isNotNull(SimulationTask::getDemandId).list();
}
// 根据任务关联的需求id查询视图中待办信息
if (CollectionUtils.isEmpty(taskList)) {
log.error("taskList为空");
return SdmResponse.failed("taskList为空");
}
List<String> demandIdList = taskList.stream().map(SimulationTask::getDemandId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (CollectionUtils.isEmpty(demandIdList)) {
log.error("demandIdList为空");
return SdmResponse.failed("demandIdList为空");
}
List<SpdmDemandVo> demandList = demandMapper.getDemandListById(demandIdList);
if (CollectionUtils.isEmpty(demandList)) {
log.error("demandList为空");
return SdmResponse.failed("demandList为空");
}
List<String> demandCodeList = demandList.stream().map(SpdmDemandVo::getDemandCode).filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (CollectionUtils.isEmpty(demandCodeList)) {
log.error("demandCodeList为空");
return SdmResponse.failed("demandCodeList为空");
}
List<LyricVTodoEmulationInfoDM> todoInfoList = lyricVTodoInfoService.lambdaQuery().in(LyricVTodoEmulationInfoDM::getTodoId, demandCodeList).list();
if (CollectionUtils.isEmpty(todoInfoList)) {
log.error("todoInfoList为空");
return SdmResponse.failed("todoInfoList为空");
}
// 构建一个需求todoId到resultFileId的映射
Map<Long,String> resultFileIdMap = todoInfoList.stream().collect(Collectors.toMap(LyricVTodoEmulationInfoDM::getTodoId,LyricVTodoEmulationInfoDM::getResultFileId,(oldValue, newValue) -> oldValue));
// 构建一个resultFileId到filePath的映射
Map<Integer,String> filePathMap = new HashMap<>();
// 查询filePath
List<String> resultFileIdStrList = todoInfoList.stream().map(LyricVTodoEmulationInfoDM::getResultFileId).filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdStrList)) {
resultFileIdStrList = splitAndDistinct(resultFileIdStrList);
List<Integer> resultFileIdList = resultFileIdStrList.stream()
.map(str -> {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("跳过无效数字:" + str);
return null; // 转换失败返回null
}
})
.filter(Objects::nonNull) // 过滤掉null值
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdList)) {
List<LyricVAttachmentConfigToDM> attachmentConfigToDMList = lyricVAttachmentConfigService.lambdaQuery().in(LyricVAttachmentConfigToDM::getId, resultFileIdList)
.list();
if (CollectionUtils.isNotEmpty(attachmentConfigToDMList)) {
filePathMap = attachmentConfigToDMList.stream().collect(Collectors.toMap(LyricVAttachmentConfigToDM::getId,LyricVAttachmentConfigToDM::getFilePath,(oldValue, newValue) -> oldValue));
}
}
}
Map<String, List<SimulationTask>> taskMap = taskList.stream().collect(Collectors.groupingBy(SimulationTask::getDemandId));
for (SpdmDemandVo simulationDemand : demandList) {
List<String> reportFileUrlList = new ArrayList<>();
String demandCode = simulationDemand.getDemandCode();
String reportFileUrl = null;
if (StringUtils.isNotBlank(demandCode) && isConvertibleToLong(demandCode)) {
// resultFileId可能有多个逗号隔开
String resultFileIdStr = resultFileIdMap.get(Long.valueOf(demandCode));
if (StringUtils.isNotBlank(resultFileIdStr)) {
try {
for (String resultFileId : Arrays.stream(resultFileIdStr.split(",")).toList()) {
reportFileUrl = filePathMap.get(Integer.parseInt(resultFileId));
if (StringUtils.isBlank(reportFileUrl)) {
continue;
}
reportFileUrlList.add(reportFileUrl);
}
} catch (NumberFormatException e) {
log.error("手动跳过无效数字:{}",resultFileIdStr);
}
}
}
if (CollectionUtils.isEmpty(reportFileUrlList)) {
continue;
}
List<SimulationTask> eachTaskList = taskMap.get(simulationDemand.getUuid());
if (CollectionUtils.isEmpty(eachTaskList)) {
continue;
}
for (SimulationTask simulationTask : eachTaskList) {
simulationTask.setReportFileUrlList(reportFileUrlList);
}
}
log.info("共处理{}条任务的报告数据",taskList.size());
for (SimulationTask task : taskList) {
// 异步下载待办的结果文件到任务文件夹下
if (CollectionUtils.isEmpty(task.getReportFileUrlList())) {
continue;
}
TagReq tagReq = new TagReq();
BeanUtils.copyProperties(task,tagReq);
tagReq.setTaskId(task.getUuid());
tagReq.setTaskId(task.getTaskName() );
CompletableFuture.runAsync(() -> {
String savePath = REPORT_PATH_PREFIX + task.getUuid();
try {
FilesUtil.downloadFile(task.getReportFileUrlList(), savePath);
// 上传到minio
String fileName = "";
FileInputStream fileInputStream = new FileInputStream(REPORT_PATH_PREFIX + task.getUuid() + File.separator + fileName);
byte[] fileData = fileInputStream.readAllBytes();
MockMultipartFile multipartFile = new MockMultipartFile(
fileName,
fileName,
"application/octet-stream",
fileData);
UploadFilesReq fileReq = new UploadFilesReq();
fileReq.setFile(multipartFile);
// 传任务uuid
fileReq.setUuid(task.getUuid());
fileReq.setFileName(fileName);
fileReq.setFileTypeDictValue(String.valueOf(FileBizTypeEnum.REPORT_FILE.getValue()));
fileReq.setFileTypeDictClass(FileDictTagEnum.FILE_TYPE.getDictClass());
fileReq.setDictTags(Arrays.asList(FileDictTagEnum.FILE_TYPE.getDictClassFieldName(), FileDictTagEnum.FILE_TYPE.getDictValueFieldName()));
fileReq.setTagReq(tagReq);
if (fileReq.getTagReq() != null) {
fileReq.setTagReqStr(JSON.toJSONString(fileReq.getTagReq()));
}
SdmResponse uploadRespond = dataFeignClient.uploadFiles(fileReq);
log.info("手动上传仿真报告到minio的响应值为{}",uploadRespond);
} catch (IOException e) {
log.error("手动上传仿真报告到minio的异常{}",e.getMessage());
}finally {
try {
FilesUtil.deleteFolderNonRecursive(savePath);
} catch (IOException e) {
log.error("手动删除临时文件夹异常:{}",e.getMessage());
}
}
});
}
return SdmResponse.success();
}
/**
* 项目的当前阶段包含:设计,就是:项目承接主体+结构,否则就是:项目承接主体+技术中心+结构,所对应的人
*

View File

@@ -90,6 +90,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.sdm.project.service.impl.LyricInternalServiceImpl.splitAndDistinct;
import static java.util.Collections.emptyList;
@Slf4j
@@ -209,6 +210,9 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
@Value("${lyricFlag:1}")
private int lyricFlag;
@Autowired
private LyricVAttachmentConfigService lyricVAttachmentConfigService;
@Transactional
@Override
@@ -3576,9 +3580,9 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
// 根据todoId去重保留首次出现的待办
todoInfoList = todoInfoList.stream()
// 过滤掉todoId为null的数据
.filter(dm -> dm.getTodoId() != null)
.filter(dm -> dm.getSubject() != null)
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(LyricVTodoEmulationInfoDM::getTodoId))),
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(LyricVTodoEmulationInfoDM::getSubject))),
ArrayList::new
));
@@ -3669,16 +3673,15 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
}
// 提取已存在的需求编码
Set<String> existingDemandCodeSet = allDemandList.stream()
.map(SpdmDemandVo::getDemandCode)
Set<String> existingDemandNameSet = allDemandList.stream()
.map(SpdmDemandVo::getDemandName)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
// 过滤已同步的待办
return todoInfoList.stream()
.filter(todoInfo -> {
String todoIdStr = String.valueOf(todoInfo.getTodoId());
return !existingDemandCodeSet.contains(todoIdStr);
return !existingDemandNameSet.contains(todoInfo.getSubject());
})
.collect(Collectors.toList());
}
@@ -3724,13 +3727,45 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
List<CIDUserResp> userList = pageDataRespSdmResponse.getData().getData();
usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId));
}
// 构建一个需求todoId到resultFileId的映射
Map<Long,String> resultFileIdMap = todoInfoList.stream().collect(Collectors.toMap(LyricVTodoEmulationInfoDM::getTodoId,LyricVTodoEmulationInfoDM::getResultFileId,(oldValue, newValue) -> oldValue));
// 构建一个resultFileId到filePath的映射
Map<Integer,String> filePathMap = new HashMap<>();
// 查询filePath
List<String> resultFileIdStrList = todoInfoList.stream().map(LyricVTodoEmulationInfoDM::getResultFileId).filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdStrList)) {
resultFileIdStrList = splitAndDistinct(resultFileIdStrList);
List<Integer> resultFileIdList = resultFileIdStrList.stream()
.map(str -> {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("跳过无效数字:" + str);
return null; // 转换失败返回null
}
})
.filter(Objects::nonNull) // 过滤掉null值
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(resultFileIdList)) {
List<LyricVAttachmentConfigToDM> attachmentConfigToDMList = lyricVAttachmentConfigService.lambdaQuery().in(LyricVAttachmentConfigToDM::getId, resultFileIdList)
.list();
if (CollectionUtils.isNotEmpty(attachmentConfigToDMList)) {
filePathMap = attachmentConfigToDMList.stream().collect(Collectors.toMap(LyricVAttachmentConfigToDM::getId,LyricVAttachmentConfigToDM::getFilePath,(oldValue, newValue) -> oldValue));
}
}
}
// 筛选出所有工位节点
for (LyricVTodoEmulationInfoDM todoItem : todoInfoList) {
try {
String demandUuid = RandomUtil.generateString(32);
// 1. 构建基础需求信息
SpdmAddDemandReq demandAddReq = buildDemandAddReq(todoItem, demandUuid, projectNodeMap, currentTimeStr,workspaceNodeMap,usernameToUserIdMap);
SpdmAddDemandReq demandAddReq = buildDemandAddReq(todoItem, demandUuid, projectNodeMap, currentTimeStr,workspaceNodeMap,usernameToUserIdMap,resultFileIdMap,filePathMap);
// 2. 构建成员信息和权限信息
List<SpdmDemandRelateMemberReq> memberList = buildDemandMemberList(
@@ -3750,7 +3785,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
demandDirNodeList.add(demandDirNode);
// 4. 异步保存需求和成员信息
saveDemandAndMembersAsync(demandAddReq, memberList, tenantId, currentUserId, usernameToUserIdMap);
saveDemandAndMembersAsync(demandAddReq, memberList, tenantId, currentUserId, usernameToUserIdMap,resultFileIdMap,filePathMap);
} catch (Exception e) {
log.error("处理待办事项失败待办ID{},错误信息:{}", todoItem.getTodoId(), e.getMessage(), e);
@@ -3768,7 +3803,9 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
Map<String, SpdmProjectNodeEditReq> projectNodeMap,
String currentTimeStr,
Map<String, String> workspaceNodeMap,
Map<String, Long> usernameToUserIdMap) {
Map<String, Long> usernameToUserIdMap,
Map<Long,String> resultFileIdMap,
Map<Integer,String> filePathMap) {
SpdmAddDemandReq demandAddReq = new SpdmAddDemandReq();
// 基础属性
@@ -3798,6 +3835,30 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
demandAddReq.setMachineId(workspaceNodeMap.get(demandAddReq.getWorkspaceId()));
}
demandAddReq.setCreator(usernameToUserIdMap.get(todoItem.getIntroduceBy()));
List<String> reportFileUrlList = new ArrayList<>();
String demandCode = demandAddReq.getDemandCode();
String reportFileUrl = null;
if (StringUtils.isNotBlank(demandCode) && isConvertibleToLong(demandCode)) {
// resultFileId可能有多个逗号隔开
String resultFileIdStr = resultFileIdMap.get(Long.valueOf(demandCode));
if (StringUtils.isNotBlank(resultFileIdStr)) {
try {
for (String resultFileId : Arrays.stream(resultFileIdStr.split(",")).toList()) {
reportFileUrl = filePathMap.get(Integer.parseInt(resultFileId));
if (StringUtils.isBlank(reportFileUrl)) {
continue;
}
reportFileUrlList.add(reportFileUrl);
}
} catch (NumberFormatException e) {
log.error("跳过无效数字:{}",resultFileIdStr);
}
}
}
if (CollectionUtils.isNotEmpty(reportFileUrlList)) {
demandAddReq.setReportFileUrlList(reportFileUrlList);
}
return demandAddReq;
}
@@ -4001,7 +4062,9 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
List<SpdmDemandRelateMemberReq> memberList,
Long tenantId,
Long currentUserId,
Map<String, Long> usernameToUserIdMap) {
Map<String, Long> usernameToUserIdMap,
Map<Long,String> resultFileIdMap,
Map<Integer,String> filePathMap) {
CompletableFuture.runAsync(() -> {
try {
ThreadLocalContext.setTenantId(tenantId);
@@ -4024,7 +4087,13 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
SimulationDemand demand = new SimulationDemand();
BeanUtils.copyProperties(demandAddReq, demand);
demand.setCreator(currentUserId);
simulationTaskService.batchCreateTaskFromDemand(List.of(demand));
simulationTaskService.batchCreateTaskFromDemand(List.of(demand),true);
log.info("异步保存需求成功需求ID{}", demandAddReq.getUuid());
} catch (Exception e) {
log.error("异步保存需求失败需求ID{}", demandAddReq.getUuid(), e);

View File

@@ -1,13 +1,12 @@
package com.sdm.project.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sdm.common.common.SdmResponse;
import com.sdm.common.common.ThreadLocalContext;
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.enums.*;
import com.sdm.common.entity.req.data.*;
import com.sdm.common.feign.inter.data.IDataFeignClient;
import com.sdm.common.utils.FilesUtil;
@@ -34,6 +33,8 @@ import com.sdm.project.model.entity.SimulationTaskExtra;
import com.sdm.common.enums.DemandMemberTypeEnum;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@@ -43,6 +44,7 @@ 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.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
@@ -85,7 +87,7 @@ public class SimulationTaskServiceImpl extends ServiceImpl<SimulationTaskMapper,
@Autowired
private IProjectService projectService;
private static final String REPORT_PATH_PREFIX = "/opt/demand/report/";
public static final String REPORT_PATH_PREFIX = "/opt/demand/report/";
@Override
@@ -140,7 +142,7 @@ public class SimulationTaskServiceImpl extends ServiceImpl<SimulationTaskMapper,
* @param demandList 需求列表
*/
@Override
public void batchCreateTaskFromDemand(List<SimulationDemand> demandList) {
public void batchCreateTaskFromDemand(List<SimulationDemand> demandList,Boolean isDownloadFlag) {
log.info("从需求批量创建任务,需求数量:{}", demandList);
if (CollectionUtils.isEmpty(demandList)) {
return;
@@ -224,30 +226,50 @@ public class SimulationTaskServiceImpl extends ServiceImpl<SimulationTaskMapper,
tagReq.setTaskId(task.getUuid());
tagReq.setTaskId(task.getTaskName() );
createTaskDir(task.getUuid(), workspaceId, task.getTaskName(),tagReq);
if (!isDownloadFlag) {
continue;
}
// 异步下载待办的结果文件到任务文件夹下
// if (StringUtils.isBlank(task.getReportFileUrl())) {
// continue;
// }
// CompletableFuture.runAsync(() -> {
// try {
// FilesUtil.downloadFile(task.getReportFileUrl(), REPORT_PATH_PREFIX + task.getUuid());
// // 上传到minio
// UploadFilesReq fileReq = new UploadFilesReq();
// fileReq.setSourceFiles();
// fileReq.setUploadTaskId();
// fileReq.setType();
// fileReq.setFileType();
// fileReq.setUuid();
// fileReq.setFileTypeDictValue();
// fileReq.setFileTypeDictClass();
// fileReq.setDisciplineDictValue();
// fileReq.setDisciplineTypeDictClass();
// fileReq.setDictTags();
// SdmResponse uploadRespond = dataFeignClient.uploadFiles(fileReq);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// });
if (CollectionUtils.isEmpty(task.getReportFileUrlList())) {
continue;
}
CompletableFuture.runAsync(() -> {
String savePath = REPORT_PATH_PREFIX + task.getUuid();
try {
FilesUtil.downloadFile(task.getReportFileUrlList(), savePath);
// 上传到minio
String fileName = "";
FileInputStream fileInputStream = new FileInputStream(REPORT_PATH_PREFIX + task.getUuid() + File.separator + fileName);
byte[] fileData = fileInputStream.readAllBytes();
MockMultipartFile multipartFile = new MockMultipartFile(
fileName,
fileName,
"application/octet-stream",
fileData);
UploadFilesReq fileReq = new UploadFilesReq();
fileReq.setFile(multipartFile);
// 传任务uuid
fileReq.setUuid(task.getUuid());
fileReq.setFileName(fileName);
fileReq.setFileTypeDictValue(String.valueOf(FileBizTypeEnum.REPORT_FILE.getValue()));
fileReq.setFileTypeDictClass(FileDictTagEnum.FILE_TYPE.getDictClass());
fileReq.setDictTags(Arrays.asList(FileDictTagEnum.FILE_TYPE.getDictClassFieldName(), FileDictTagEnum.FILE_TYPE.getDictValueFieldName()));
fileReq.setTagReq(tagReq);
if (fileReq.getTagReq() != null) {
fileReq.setTagReqStr(JSON.toJSONString(fileReq.getTagReq()));
}
SdmResponse uploadRespond = dataFeignClient.uploadFiles(fileReq);
log.info("上传仿真报告到minio的响应值为{}",uploadRespond);
} catch (IOException e) {
log.error("上传仿真报告到minio的异常{}",e.getMessage());
}finally {
try {
FilesUtil.deleteFolderNonRecursive(savePath);
} catch (IOException e) {
log.error("删除临时文件夹异常:{}",e.getMessage());
}
}
});
}
// 批量更新任务权限(使用批量接口)
batchUpdateTaskPermissions(tasksToCreate);
@@ -274,6 +296,9 @@ public class SimulationTaskServiceImpl extends ServiceImpl<SimulationTaskMapper,
// 动态设置 tag
setTaskTags(task, demand, tagMap);
// 设置待办的报告路径
task.setReportFileUrlList(demand.getReportFileUrlList());
return task;
}