Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-02-12 10:19:32 +08:00
13 changed files with 308 additions and 79 deletions

View File

@@ -4,10 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "从回收站彻底删除请求")
public class PermanentDeleteFromRecycleReq {
@Schema(description = "要彻底删除的文件/目录ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件/目录ID不能为空")
private Long id;
@Schema(description = "要彻底删除的文件/目录ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件/目录ID列表不能为空")
private List<Long> ids;
}

View File

@@ -4,10 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "从回收站还原请求")
public class RestoreFromRecycleReq {
@Schema(description = "要还原的文件/目录ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件/目录ID不能为空")
private Long id;
@Schema(description = "要还原的文件/目录ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件/目录ID列表不能为空")
private List<Long> ids;
}

View File

@@ -0,0 +1,21 @@
package com.sdm.common.entity.req.data;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "批量更新回收站过期时间请求")
public class UpdateRecycleExpireReq {
@Schema(description = "文件/目录ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件/目录ID列表不能为空")
private List<Long> ids;
@Schema(description = "保留天数(从删除时间开始计算)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "保留天数不能为空")
@Min(value = 0, message = "保留天数不能小于0")
private Integer days;
}

View File

@@ -146,31 +146,44 @@ public class DataFileController implements IDataFeignClient {
}
/**
* 从回收站还原
* 批量从回收站还原
*
* @param req
* @return
*/
@SysLog("从回收站还原")
@PostMapping("/restoreFromRecycle")
@Operation(summary = "从回收站还原", description = "将文件/目录从回收站还原到原位置")
@Operation(summary = "从回收站还原", description = "将文件/目录从回收站还原到原位置(支持批量)")
public SdmResponse restoreFromRecycle(@RequestBody @Validated RestoreFromRecycleReq req) {
return IDataFileService.restoreFromRecycle(req);
}
/**
* 从回收站彻底删除
* 批量从回收站彻底删除
*
* @param req
* @return
*/
@SysLog("从回收站彻底删除")
@PostMapping("/permanentDeleteFromRecycle")
@Operation(summary = "从回收站彻底删除", description = "从回收站彻底删除文件/目录(物理删除,不可恢复)")
@Operation(summary = "从回收站彻底删除", description = "从回收站彻底删除文件/目录(物理删除,不可恢复,支持批量")
public SdmResponse permanentDeleteFromRecycle(@RequestBody @Validated PermanentDeleteFromRecycleReq req) {
return IDataFileService.permanentDeleteFromRecycle(req);
}
/**
* 批量更新回收站过期时间
*
* @param req
* @return
*/
@SysLog("更新回收站过期时间")
@PostMapping("/updateRecycleExpire")
@Operation(summary = "更新回收站过期时间", description = "批量更新回收站中文件/目录的过期时间")
public SdmResponse updateRecycleExpire(@RequestBody @Validated UpdateRecycleExpireReq req) {
return IDataFileService.updateRecycleExpire(req);
}
/**
* 搜索文件
*

View File

@@ -140,25 +140,34 @@ public interface IDataFileService {
* @param req 回收站列表查询请求参数
* @return 回收站列表响应
*/
default SdmResponse listRecycleBin(com.sdm.common.entity.req.data.ListRecycleBinReq req) {
default SdmResponse listRecycleBin(ListRecycleBinReq req) {
return null;
}
/**
* 从回收站还原文件/目录
* 批量从回收站还原文件/目录
* @param req 还原请求参数
* @return 还原结果响应
*/
default SdmResponse restoreFromRecycle(com.sdm.common.entity.req.data.RestoreFromRecycleReq req) {
default SdmResponse restoreFromRecycle(RestoreFromRecycleReq req) {
return null;
}
/**
* 从回收站彻底删除文件/目录
* 批量从回收站彻底删除文件/目录
* @param req 彻底删除请求参数
* @return 删除结果响应
*/
default SdmResponse permanentDeleteFromRecycle(com.sdm.common.entity.req.data.PermanentDeleteFromRecycleReq req) {
default SdmResponse permanentDeleteFromRecycle(PermanentDeleteFromRecycleReq req) {
return null;
}
/**
* 批量更新回收站过期时间
* @param req 更新过期时间请求参数
* @return 更新结果响应
*/
default SdmResponse updateRecycleExpire(com.sdm.common.entity.req.data.UpdateRecycleExpireReq req) {
return null;
}

View File

@@ -105,6 +105,10 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
private static final String FLOWABLE_SIMULATION_BASEDIR = "/home/simulation/";
@Value("${data.recycle.retention-days:7}")
private Integer recycleRetentionDays;
@Autowired
@@ -4686,8 +4690,30 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse restoreFromRecycle(RestoreFromRecycleReq req) {
if (ObjectUtils.isEmpty(req.getIds())) {
return SdmResponse.failed("未选择要还原的文件");
}
List<String> messages = new ArrayList<>();
for (Long id : req.getIds()) {
SdmResponse resp = restoreSingleFile(id);
if (!resp.isSuccess()) {
throw new RuntimeException("还原文件(ID:" + id + ")失败: " + resp.getMessage());
}
if (resp.getData() != null && !Objects.equals(resp.getData(), "还原成功")) {
messages.add(resp.getData().toString());
}
}
if (!messages.isEmpty()) {
return SdmResponse.success("还原成功,部分文件已重命名: " + String.join("; ", messages));
}
return SdmResponse.success("批量还原成功");
}
private SdmResponse restoreSingleFile(Long id) {
FileMetadataInfo metadata = fileMetadataInfoService.lambdaQuery()
.eq(FileMetadataInfo::getId, req.getId())
.eq(FileMetadataInfo::getId, id)
.isNotNull(FileMetadataInfo::getDeletedAt)
.one();
@@ -4778,7 +4804,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}
log.info("成功从回收站还原: id={}, oldKey={}, newKey={}, newName={}", metadata.getId(), oldKey, restoreKey, restoreName);
return SdmResponse.success(Objects.equals(restoreName, originalName) ? "还原成功" : "还原成功,原路径已存在,已重命名为: " + restoreName);
return SdmResponse.success(Objects.equals(restoreName, originalName) ? "还原成功" : "已重命名为: " + restoreName);
} catch (Exception e) {
log.error("还原失败", e);
@@ -4789,8 +4815,22 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse permanentDeleteFromRecycle(PermanentDeleteFromRecycleReq req) {
if (ObjectUtils.isEmpty(req.getIds())) {
return SdmResponse.failed("未选择要删除的文件");
}
for (Long id : req.getIds()) {
SdmResponse resp = permanentDeleteSingleFile(id);
if (!resp.isSuccess()) {
throw new RuntimeException("删除文件(ID:" + id + ")失败: " + resp.getMessage());
}
}
return SdmResponse.success("批量彻底删除成功");
}
private SdmResponse permanentDeleteSingleFile(Long id) {
FileMetadataInfo metadata = fileMetadataInfoService.lambdaQuery()
.eq(FileMetadataInfo::getId, req.getId())
.eq(FileMetadataInfo::getId, id)
.isNotNull(FileMetadataInfo::getDeletedAt)
.one();
@@ -4816,4 +4856,64 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse updateRecycleExpire(UpdateRecycleExpireReq req) {
if (ObjectUtils.isEmpty(req.getIds())) {
return SdmResponse.failed("未选择要更新的文件");
}
List<FileMetadataInfo> metadataList = fileMetadataInfoService.listByIds(req.getIds());
if (CollectionUtils.isEmpty(metadataList)) {
return SdmResponse.failed("文件不存在");
}
int successCount = 0;
for (FileMetadataInfo metadata : metadataList) {
// 仅处理已删除的文件
if (metadata.getDeletedAt() == null) {
continue;
}
// 计算新的过期时间:基于 deletedAt + days
LocalDateTime newExpireAt = metadata.getDeletedAt().plusDays(req.getDays());
// 如果是目录,递归更新子项
if (Objects.equals(DataTypeEnum.DIRECTORY.getValue(), metadata.getDataType())) {
updateDirectoryRecycleExpire(metadata, newExpireAt);
} else {
// 单文件更新
metadata.setRecycleExpireAt(newExpireAt);
metadata.setUpdateTime(LocalDateTime.now());
fileMetadataInfoService.updateById(metadata);
}
successCount++;
}
return SdmResponse.success("成功更新 " + successCount + " 个文件的回收站过期时间");
}
private void updateDirectoryRecycleExpire(FileMetadataInfo rootDir, LocalDateTime newExpireAt) {
// 1. 更新目录本身
rootDir.setRecycleExpireAt(newExpireAt);
rootDir.setUpdateTime(LocalDateTime.now());
fileMetadataInfoService.updateById(rootDir);
// 2. 批量更新子项(包括子目录和文件)
// 只要是该目录下的objectKey以目录key为前缀且已删除的都更新
String dirKey = rootDir.getObjectKey();
if (!dirKey.endsWith("/")) {
dirKey += "/";
}
// 使用 LambdaUpdateWrapper 批量更新,效率更高
fileMetadataInfoService.lambdaUpdate()
.likeRight(FileMetadataInfo::getObjectKey, dirKey) // objectKey like 'dirKey%'
.eq(FileMetadataInfo::getBucketName, rootDir.getBucketName())
.isNotNull(FileMetadataInfo::getDeletedAt) // 必须是已删除的
.set(FileMetadataInfo::getRecycleExpireAt, newExpireAt)
.set(FileMetadataInfo::getUpdateTime, LocalDateTime.now())
.update();
}
}

View File

@@ -101,7 +101,12 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
public SdmResponse addDemand(SpdmAddDemandReq req) {
Long tenantId = ThreadLocalContext.getTenantId();
Long jobNumber = ThreadLocalContext.getUserId();
req.setCreator(jobNumber);
String workNo = ThreadLocalContext.getJobNumber();
if (isConvertibleToLong(workNo)) {
req.setCreator(Long.valueOf(workNo));
}else {
req.setCreator(jobNumber);
}
log.info("新增需求时当前租户id为{},工号为:{}", tenantId, jobNumber);
// 获取仿真负责人
String pMemberList = req.getPMemberList();
@@ -433,10 +438,19 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
return SdmResponse.success();
}
public static String removeLeadingZeros(String jobNumber) {
if (StringUtils.isNotBlank(jobNumber)) {
return "";
}
String trimmed = jobNumber.replaceAll("^0+","");
return trimmed.isEmpty() ? "0" : trimmed;
}
@Override
public SdmResponse list(SpdmDemandListReq req) {
Long tenantId = ThreadLocalContext.getTenantId();
Long jobNumber = ThreadLocalContext.getUserId();
String jobNumber = removeLeadingZeros(ThreadLocalContext.getJobNumber());
Long currentUserId = ThreadLocalContext.getUserId();
if (ObjectUtils.isEmpty(tenantId) || ObjectUtils.isEmpty(jobNumber)) {
log.error("公司和工号都不能为空");
return SdmResponse.failed("公司和工号都不能为空");
@@ -461,10 +475,10 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
}
if (type == 0) {
// 创建人是当前用户
demandList = demandList.stream().filter(demand -> jobNumber.equals(demand.getCreator())).toList();
demandList = demandList.stream().filter(demand -> jobNumber.equals(String.valueOf(demand.getCreator()))).toList();
} else {
// 仿真负责人是当前用户
List<SpdmDemandMemberVo> pDemandMemberVoList = demandMemberVoList.stream().filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType()) && Long.valueOf(jobNumber).equals(member.getUserId())).toList();
List<SpdmDemandMemberVo> pDemandMemberVoList = demandMemberVoList.stream().filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType()) && currentUserId.equals(member.getUserId())).toList();
if (CollectionUtils.isNotEmpty(pDemandMemberVoList)) {
List<String> myDemandIdList = pDemandMemberVoList.stream().map(SpdmDemandMemberVo::getDemandId).toList();
demandList = demandList.stream().filter(demand -> myDemandIdList.contains(demand.getUuid())).toList();
@@ -1208,12 +1222,46 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
return SdmResponse.success(demandVoList);
}
/**
* 判断字符串是否可以安全转换为Long类型
* @param str 待校验的字符串
* @return true-可以转换false-不可以转换
*/
public static boolean isConvertibleToLong(String str) {
// 1. 处理null、空字符串、全空格字符串
if (str == null || str.trim().isEmpty()) {
return false;
}
String trimmedStr = str.trim();
// 2. 正则校验数字格式(支持正负号,纯数字)
// 正则说明:^-? 匹配开头的负号(可选);\\d+ 匹配1个及以上数字$ 匹配结尾
if (!trimmedStr.matches("^-?\\d+$")) {
return false;
}
// 3. 校验数值范围,避免溢出
try {
// 直接调用Long.parseLong利用其自带的范围校验
Long.parseLong(trimmedStr);
return true;
} catch (NumberFormatException e) {
// 捕获数值超出Long范围的异常
return false;
}
}
@Transactional
@Override
public SdmResponse addDemandNoPermission(SpdmAddDemandReq req) {
Long tenantId = ThreadLocalContext.getTenantId();
Long jobNumber = ThreadLocalContext.getUserId();
req.setCreator(jobNumber);
String workNo = ThreadLocalContext.getJobNumber();
if (isConvertibleToLong(workNo)) {
req.setCreator(Long.valueOf(workNo));
}else {
req.setCreator(jobNumber);
}
log.info("新增需求时无权限校验当前租户id为{},工号为:{}", tenantId, jobNumber);
// 获取仿真负责人
String pMemberList = req.getPMemberList();

View File

@@ -405,7 +405,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
try {
String demandUuid = RandomUtil.generateString(UUID_LENGTH);
// 1. 构建需求基础参数 + 成员 + 权限
SpdmAddDemandReq demandReq = buildDemandReq(todo, demandUuid, curDateStr);
SpdmAddDemandReq demandReq = buildDemandReq(todo, demandUuid, curDateStr,tenantId,usernameToUserIdMap);
List<SpdmDemandRelateMemberReq> memberList = buildDemandMemberList(todo, demandUuid, jobNumber, curDateStr);
List<SpdmDemandExtraReq> demandExtraList = buildDemandExtraList(todo, demandUuid, jobNumber, curDateStr);
// 2. 构建权限更新参数
@@ -478,7 +478,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
*/
private SpdmAddDemandReq buildDemandReq(LyricVTodoEmulationInfoDM todo,
String demandUuid,
String curDateStr) {
String curDateStr,
Long tenantId,
Map<String, Long> usernameToUserIdMap) {
SpdmAddDemandReq req = new SpdmAddDemandReq();
req.setUuid(demandUuid);
req.setDemandName(todo.getSubject());
@@ -492,7 +494,13 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
req.setEndTime(todo.getClosedTime());
req.setCreateTime(curDateStr);
req.setDemandSource(SYNC_PROJECT_SOURCE);
req.setCreator(Long.valueOf(todo.getIntroduceBy()));
if (isConvertibleToInt(todo.getIntroduceBy())) {
req.setCreator(Long.valueOf(todo.getIntroduceBy()));
}else {
req.setCreator(usernameToUserIdMap.get(todo.getIntroduceBy()));
}
req.setTenantId(tenantId);
// 补充项目/阶段/工位ID
fillProjectPhaseWorkspaceId(req, todo);
@@ -503,20 +511,18 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
* 填充需求的项目/阶段/工位ID
*/
private void fillProjectPhaseWorkspaceId(SpdmAddDemandReq req, LyricVTodoEmulationInfoDM todo) {
List<SimulationNode> allNodeList = nodeService.lambdaQuery()
SimulationNode projectNode = nodeService.lambdaQuery()
.in(SimulationNode::getNodeCode, Arrays.asList(todo.getProject(), todo.getProjectStage(), todo.getStationNum()))
.list();
.one();
if (CollectionUtils.isEmpty(allNodeList)) {
if (ObjectUtils.isEmpty(projectNode)) {
return;
}
// 填充需求的项目ID
allNodeList.stream()
.filter(node -> NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())
&& node.getNodeCode().equals(todo.getProject()))
.findFirst()
.ifPresent(node -> req.setProjectId(node.getUuid()));
req.setProjectId(projectNode.getUuid());
List<SimulationNode> allNodeList = nodeService.lambdaQuery().eq(SimulationNode::getTag1, projectNode.getUuid()).list();
// 填充需求的阶段ID
allNodeList.stream()
@@ -694,13 +700,17 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
try {
demandMapper.addDemand(demandReq, tenantId, demandReq.getCreator());
if (CollectionUtils.isNotEmpty(memberList)) {
List<SpdmDemandRelateMemberReq> normalMemberList = new ArrayList<>();
for (SpdmDemandRelateMemberReq member : memberList) {
Long cidUserId = usernameToUserIdMap.get(String.valueOf(member.getUserId()));
if (cidUserId != null) {
member.setUserId(cidUserId);
Long cidUserId = usernameToUserIdMap.get(member.getUserIdStr());
if (cidUserId == null) {
log.info("工号为:{}的用户未查询到用户id", member.getUserIdStr());
continue;
}
member.setUserId(cidUserId);
normalMemberList.add(member);
}
demandMapper.addDemandMember(memberList);
demandMapper.addDemandMember(normalMemberList);
}
if (CollectionUtils.isNotEmpty(demandExtraList)) {
demandMapper.addDemandExtra(demandExtraList);
@@ -2238,10 +2248,12 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
// 关联的项目未在系统
// 取项目视图、工位相关视图构建项目树信息(只同步当前阶段)创建任务(不创建任务文件夹,等下发时进行创建)
if (CollectionUtils.isNotEmpty(noRelatedProjectVTodoEmulationInfoDMList)) {
SdmResponse response = httpSyncHandleNoRelatedProjectTodo(noRelatedProjectVTodoEmulationInfoDMList, tenantId, jobNumber);
log.info("httpSyncHandleNoRelatedProjectTodo响应值为{}",response);
if (!response.isSuccess()) {
return response;
List<SpdmProjectNodeEditReq> spdmProjectNodeEditReqList = httpSyncHandleNoRelatedProjectTodo(noRelatedProjectVTodoEmulationInfoDMList, tenantId, jobNumber);
log.info("httpSyncHandleNoRelatedProjectTodo响应值为{}",spdmProjectNodeEditReqList);
for (SpdmProjectNodeEditReq spdmProjectNodeEditReq : spdmProjectNodeEditReqList) {
SimulationNode simulationNode = new SimulationNode();
BeanUtils.copyProperties(spdmProjectNodeEditReq,simulationNode);
projectNodeList.add(simulationNode);
}
}
@@ -2252,57 +2264,61 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
return response;
}
private SdmResponse httpSyncHandleNoRelatedProjectTodo(List<LyricVTodoEmulationInfoDM> noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) {
CompletableFuture<SdmResponse> syncHandleNoRelatedProjectTodoFeature = CompletableFuture.supplyAsync(() ->
private List<SpdmProjectNodeEditReq> httpSyncHandleNoRelatedProjectTodo(List<LyricVTodoEmulationInfoDM> noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) {
CompletableFuture<List<SpdmProjectNodeEditReq>> syncHandleNoRelatedProjectTodoFeature = CompletableFuture.supplyAsync(() ->
handleNoRelatedProjectTodo(noRelatedProjectVTodoEmulationInfoDMList, tenantId, jobNumber));
try {
SdmResponse sdmResponse = syncHandleNoRelatedProjectTodoFeature.get(syncProjectDataWaitSeconds, TimeUnit.SECONDS);
return sdmResponse;
List<SpdmProjectNodeEditReq> spdmProjectNodeEditReqList = syncHandleNoRelatedProjectTodoFeature.get(syncProjectDataWaitSeconds, TimeUnit.SECONDS);
return spdmProjectNodeEditReqList;
} catch (InterruptedException e) {
log.error("同步项目信息异常终止:{}", e.getMessage());
return SdmResponse.failed("同步项目信息异常终止");
return new ArrayList<>();
} catch (ExecutionException e) {
log.error("同步项目信息执行错误:{}", e.getMessage());
return SdmResponse.failed("同步项目信息执行出错误");
return new ArrayList<>();
} catch (TimeoutException e) {
log.warn("同步项目信息执行超时:{}", e.getMessage());
return SdmResponse.success("同步项目信息执行中,请稍后");
return new ArrayList<>();
} catch (Exception e) {
log.error("同步项目信息未知错误:{}", e.getMessage());
return SdmResponse.failed("同步项目信息未知错误");
return new ArrayList<>();
}
}
private SdmResponse handleNoRelatedProjectTodo(List<LyricVTodoEmulationInfoDM> noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) {
private List<SpdmProjectNodeEditReq> handleNoRelatedProjectTodo(List<LyricVTodoEmulationInfoDM> noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) {
// 尝试获取锁(立即返回,不等待)
if (!syncTodoInfoProjectLock.tryLock()) {
return SdmResponse.success("有数据同步任务(同步项目信息)正在执行中,请稍后再试");
return new ArrayList<>();
}
// 取项目视图、工位相关视图构建项目树信息(只同步当前阶段)
// 根据待办获取所有项目编号
List<SpdmProjectNodeEditReq> spdmProjectNodeEditReqList = new ArrayList<>();
try {
List<String> projectNumList = noRelatedProjectVTodoEmulationInfoDMList.stream().map(LyricVTodoEmulationInfoDM::getProject)
.filter(StringUtils::isNotBlank).distinct().toList();
if (CollectionUtils.isEmpty(projectNumList)) {
log.info("projectNumList为空");
return SdmResponse.success("projectNumList为空");
return new ArrayList<>();
}
// 根据项目编号查询项目视图获取项目信息
List<LyricVProjectToDM> lyricVProjectToDMList = lyricVProjectToDmService.lambdaQuery().in(LyricVProjectToDM::getProjectNum, projectNumList).list();
if (CollectionUtils.isEmpty(lyricVProjectToDMList)) {
log.info("lyricVProjectToDMList为空");
return SdmResponse.success("lyricVProjectToDMList为空");
return new ArrayList<>();
}
for (LyricVProjectToDM lyricVProjectToDM : lyricVProjectToDMList) {
buildProjectForTodoInfo(lyricVProjectToDM, tenantId, jobNumber);
SpdmProjectNodeEditReq spdmProjectNodeEditReq = buildProjectForTodoInfo(lyricVProjectToDM, tenantId, jobNumber);
if (spdmProjectNodeEditReq != null) {
spdmProjectNodeEditReqList.add(spdmProjectNodeEditReq);
}
}
}catch (Exception e) {
log.error("handleNoRelatedProjectTodo 未知 error: {}", e.getMessage());
return SdmResponse.failed();
return new ArrayList<>();
} finally {
syncTodoInfoProjectLock.unlock();
}
return SdmResponse.success();
return spdmProjectNodeEditReqList;
}
public static String getTagProperty(Object obj, String propertyName) throws Exception {
@@ -2570,7 +2586,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
log.info("创建节点时,调用批量创建文件夹的返回值为:{}", response);
}
private void buildProjectForTodoInfo(LyricVProjectToDM lyricVProjectToDM, Long tenantId, Long jobNumber) {
private SpdmProjectNodeEditReq buildProjectForTodoInfo(LyricVProjectToDM lyricVProjectToDM, Long tenantId, Long jobNumber) {
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
List<SpdmProjectNodeEditReq> currentNodeList;
List<SpdmProjectNodeEditReq> addNodeList = new ArrayList<>();
@@ -2734,7 +2750,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
}
if (nodeMapper.addNodeBatch(addNodeList) <= 0) {
return ;
return null;
}
// 保存拓展字段
@@ -2874,6 +2890,8 @@ public class LyricInternalServiceImpl implements ILyricInternalService {
SdmResponse response = dataFeignClient.batchUpdatePermission(batchReq);
log.info("同步待办拉取项目时,批量更新权限结果为:{}",response);
}
return spdmProjectNodeEditReq;
}

View File

@@ -393,8 +393,8 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
taskNodePoList = taskService.lambdaQuery().eq(SimulationTask::getTag2,nodeId).list();
}
if (CollectionUtils.isNotEmpty(taskNodePoList)) {
nodeMapper.deleteTaskBatch(deleteNodeIdList);
List<String> taskIdList = taskNodePoList.stream().map(SimulationTask::getUuid).toList();
taskService.lambdaUpdate().in(SimulationTask::getUuid,taskIdList).remove();
nodeMapper.deleteTaskExtraBatch(taskIdList);
nodeMapper.deleteTaskMemberBatch(taskIdList);
// 删除当前节点及子节点下的指标相关信息

View File

@@ -253,13 +253,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
}
String realTag = realTagObj.getKey();
String realTagId = realTagObj.getValue();
Long userId = ThreadLocalContext.getUserId();
SdmResponse<CIDUserResp> currentCidUserResp = sysUserFeignClient.queryUserDetail(UserQueryReq.builder().userId(userId).build());
if (ObjectUtils.isEmpty(currentCidUserResp.getData())) {
log.error("根据userId{},未查询到用户", userId);
return ;
}
Long curUserId = currentCidUserResp.getData().getUserId();
Long curUserId = ThreadLocalContext.getUserId();
// 查询当前节点下任务
List<TaskNodePo> currentNodeAssociatedTaskList = new ArrayList<>();
int currentNodeDepth = getCurrentNodeDepth(projectNodePo);
@@ -313,19 +307,41 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
}
}
}
SdmResponse<List<CIDUserResp>> cidUserResp = sysUserFeignClient.listUserByIds(UserQueryReq.builder().userIds(memberList.stream().map(SimulationTaskMember::getUserId).toList()).build());
if (ObjectUtils.isEmpty(cidUserResp)) {
return;
}
List<CIDUserResp> cidUserRespList = cidUserResp.getData();
if (CollectionUtils.isEmpty(cidUserRespList)) {
return;
}
Map<Long, CIDUserResp> cidUserMap = cidUserRespList.stream().collect(Collectors.toMap(CIDUserResp::getUserId, Function.identity()));
// 查询当前任务的负责人和执行人
for (TaskNodePo taskNodePo : currentNodeAssociatedTaskList) {
if (CollectionUtils.isNotEmpty(memberList)) {
List<Long> eUserIdList = memberList.stream().filter(member -> MemberTypeEnum.EXECUTOR.getCode().equals(member.getType())).map(SimulationTaskMember::getUserId).distinct().toList();
List<Long> pUserIdList = memberList.stream().filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType())).map(SimulationTaskMember::getUserId).distinct().toList();
if (CollectionUtils.isNotEmpty(eUserIdList)) {
SdmResponse<List<CIDUserResp>> cidUserResp = sysUserFeignClient.listUserByIds(UserQueryReq.builder().userIds(eUserIdList).build());
taskNodePo.setEMemberList(cidUserResp.getData());
List<Long> eUserIdList = memberList.stream().filter(member -> MemberTypeEnum.EXECUTOR.getCode().equals(member.getType()) && taskNodePo.getUuid().equals(member.getTaskId())).map(SimulationTaskMember::getUserId).distinct().toList();
List<Long> pUserIdList = memberList.stream().filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType()) && taskNodePo.getUuid().equals(member.getTaskId())).map(SimulationTaskMember::getUserId).distinct().toList();
if (CollectionUtils.isNotEmpty(eUserIdList)) {
List<CIDUserResp> eUserList = new ArrayList<>();
for (Long eUserId : eUserIdList) {
CIDUserResp eCidUser = cidUserMap.get(eUserId);
if (ObjectUtils.isEmpty(eCidUser)) {
continue;
}
eUserList.add(eCidUser);
}
if (CollectionUtils.isNotEmpty(pUserIdList)) {
SdmResponse<List<CIDUserResp>> cidUserResp = sysUserFeignClient.listUserByIds(UserQueryReq.builder().userIds(pUserIdList).build());
taskNodePo.setPMemberList(cidUserResp.getData());
taskNodePo.setEMemberList(eUserList);
}
if (CollectionUtils.isNotEmpty(pUserIdList)) {
List<CIDUserResp> pUserList = new ArrayList<>();
for (Long eUserId : pUserIdList) {
CIDUserResp pCidUser = cidUserMap.get(eUserId);
if (ObjectUtils.isEmpty(pCidUser)) {
continue;
}
pUserList.add(pCidUser);
}
taskNodePo.setPMemberList(pUserList);
}
}
}

View File

@@ -295,7 +295,7 @@ public class TaskServiceImpl implements ITaskService {
List<SpdmDemandVo> demandVoList = demandMapper.getDemandListById(demandIdList);
demandMap = demandVoList.stream()
.collect(Collectors.toMap(SpdmDemandVo::getUuid, Function.identity()));
demandSubmitMap = demandVoList.stream()
demandSubmitMap = demandVoList.stream().filter(spdmDemandVo -> ObjectUtils.isNotEmpty(spdmDemandVo.getCreator()))
.collect(Collectors.toMap(SpdmDemandVo::getUuid, SpdmDemandVo::getCreator));
}

View File

@@ -8,7 +8,7 @@
insert into simulation_demand (uuid,demand_name,demand_code,demand_type,sim_type,demand_status,achieve_status,progress,approval_status,
begin_time,end_time,finish_time,project_id,phase_id,workspace_id,tenant_id,creator,create_time,demandSource,description,machine_id) values
(#{req.uuid},#{req.demandName},#{req.demandCode},#{req.demandType},#{req.simType},#{req.demandStatus},#{req.achieveStatus},#{req.progress},#{req.approvalStatus},
#{req.beginTime},#{req.endTime},'',#{req.projectId},#{req.phaseId},#{req.workspaceId},#{tenantId},#{jobNumber},#{req.createTime},#{req.demandSource},#{req.description},#{req.machineId})
#{req.beginTime},#{req.endTime},'',#{req.projectId},#{req.phaseId},#{req.workspaceId},#{req.creator},#{jobNumber},#{req.createTime},#{req.demandSource},#{req.description},#{req.machineId})
</insert>
<insert id="addDemandMember">

View File

@@ -36,7 +36,7 @@
<insert id="saveBatchTaskExtra">
insert into simulation_task_extra (task_id, property_name, property_value, value_type, property_class, creator, create_time) values
<foreach collection='list' item='taskExtra' index='index' separator=','>
(#{taskExtra.taskId}}, #{taskExtra.propertyName}, #{taskExtra.propertyValue}, #{taskExtra.valueType}, #{taskExtra.propertyClass}, #{taskExtra.creator}, #{taskExtra.createTime})
(#{taskExtra.taskId}, #{taskExtra.propertyName}, #{taskExtra.propertyValue}, #{taskExtra.valueType}, #{taskExtra.propertyClass}, #{taskExtra.creator}, #{taskExtra.createTime})
</foreach>
</insert>