fix:更细工位所有结构细化完成时间、工位升级时间、清单下发时间

This commit is contained in:
2026-01-27 10:40:34 +08:00
parent 81de41f7f7
commit 36fdc6b70b
6 changed files with 299 additions and 0 deletions

View File

@@ -139,6 +139,18 @@ public class SimulationNodeController implements ISimulationNodeFeignClient {
return nodeService.getDedicatedTime(req);
}
/**
* 批量更新工位扩展属性
* @param req
* @return
*/
@SysLog("批量更新工位扩展属性")
@PostMapping("/batchUpdateWorkspaceExtra")
@Operation(summary = "批量更新工位扩展属性", description = "批量更新工位扩展属性")
public SdmResponse batchUpdateWorkspaceExtra(@RequestBody @Validated BatchUpdateWorkspaceExtraReq req) {
return nodeService.batchUpdateWorkspaceExtra(req);
}
/**
* 根据节点类型获取所有节点
*

View File

@@ -27,6 +27,12 @@ public interface SimulationNodeMapper extends BaseMapper<SimulationNode> {
int editNodeExtra(@Param("nodeExtra") SpdmNodeExtraReq nodeExtra);
/**
* 更新节点扩展属性支持null值更新
* 与editNodeExtra的区别此方法明确支持将propertyValue更新为null
*/
int editNodeExtraWithNull(@Param("nodeExtra") SpdmNodeExtraReq nodeExtra);
int deleteNodeBatch(@Param("deleteNodeIdList") List<String> deleteNodeIdList);
int deleteNodeMemberBatch(@Param("deleteNodeIdList") List<String> deleteNodeIdList);

View File

@@ -36,6 +36,8 @@ public interface INodeService extends IService<SimulationNode> {
SdmResponse getDedicatedTime(GetDedicatedTimeReq req);
SdmResponse batchUpdateWorkspaceExtra(BatchUpdateWorkspaceExtraReq req);
SdmResponse<List<AllNodeByProjectIdAndTypeResp>> getAllNodeByBodeType(String nodeType, Long nodeId);
SdmResponse<List<AllNodeByProjectIdAndTypeResp>> getAllNodeByProjectIdAndType(List<String> uuids, String nextNodeType);

View File

@@ -51,6 +51,7 @@ import com.sdm.project.model.resp.YA.BosimSaveProjectTaskRsp;
import com.sdm.project.model.vo.*;
import com.sdm.project.service.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
@@ -1444,6 +1445,195 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse batchUpdateWorkspaceExtra(BatchUpdateWorkspaceExtraReq req) {
try {
BatchUpdateContext context = buildUpdateContext(req);
validateWorkspaces(context.getWorkspaceUuids());
processWorkspaceExtras(context);
executeBatchOperations(context);
log.info("[batchUpdateWorkspaceExtra] 批量更新工位扩展属性成功,工位数量={},更新数量={},新增数量={}",
context.getWorkspaceUuids().size(), context.getUpdateList().size(), context.getInsertList().size());
return SdmResponse.success("批量更新工位扩展属性成功");
} catch (IllegalArgumentException | IllegalStateException e) {
log.error("[batchUpdateWorkspaceExtra] 批量更新工位扩展属性失败", e);
return SdmResponse.failed(e.getMessage());
} catch (Exception e) {
log.error("[batchUpdateWorkspaceExtra] 批量更新工位扩展属性异常", e);
return SdmResponse.failed("批量更新工位扩展属性失败:" + e.getMessage());
}
}
/**
* 构建批量更新上下文,封装所有相关数据
*/
private BatchUpdateContext buildUpdateContext(BatchUpdateWorkspaceExtraReq req) {
List<BatchUpdateWorkspaceExtraReq.WorkspaceExtraData> workspaceExtrasList = req.getWorkspaceExtras();
if (CollectionUtils.isEmpty(workspaceExtrasList)) {
throw new IllegalArgumentException("工位扩展属性列表不能为空");
}
List<String> workspaceUuids = workspaceExtrasList.stream()
.map(BatchUpdateWorkspaceExtraReq.WorkspaceExtraData::getWorkspaceUuid)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(workspaceUuids)) {
throw new IllegalArgumentException("工位UUID列表不能为空");
}
Set<String> propertyNames = workspaceExtrasList.stream()
.flatMap(data -> data.getExtras().stream()
.map(BatchUpdateWorkspaceExtraReq.WorkspaceExtraItem::getPropertyName))
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(propertyNames)) {
throw new IllegalArgumentException("属性名称列表不能为空");
}
Map<String, Map<String, SimulationNodeExtra>> existingExtrasMap =
simulationNodeExtraService.batchGetNodeExtraMap(workspaceUuids, new ArrayList<>(propertyNames));
Long userId = ThreadLocalContext.getUserId();
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
UserContext userContext = new UserContext(userId, currentTime);
return new BatchUpdateContext(workspaceExtrasList, workspaceUuids, existingExtrasMap, userContext);
}
/**
* 验证工位存在性
*/
private void validateWorkspaces(List<String> workspaceUuids) {
List<SimulationNode> existingWorkspaces = this.lambdaQuery()
.in(SimulationNode::getUuid, workspaceUuids)
.eq(SimulationNode::getNodeType, NodeTypeEnum.WORKSPACE.getValue())
.list();
if (existingWorkspaces.size() != workspaceUuids.size()) {
throw new IllegalStateException(
String.format("部分工位不存在,期望数量=%d实际数量=%d", workspaceUuids.size(), existingWorkspaces.size()));
}
}
/**
* 处理工位扩展属性,构建更新和新增列表
*/
private void processWorkspaceExtras(BatchUpdateContext context) {
for (BatchUpdateWorkspaceExtraReq.WorkspaceExtraData workspaceData : context.getWorkspaceExtrasList()) {
String workspaceUuid = workspaceData.getWorkspaceUuid();
if (StringUtils.isBlank(workspaceUuid) || CollectionUtils.isEmpty(workspaceData.getExtras())) {
if (StringUtils.isBlank(workspaceUuid)) {
log.warn("[batchUpdateWorkspaceExtra] 工位UUID为空跳过");
} else {
log.warn("[batchUpdateWorkspaceExtra] 工位{}的扩展属性列表为空,跳过", workspaceUuid);
}
continue;
}
Map<String, SimulationNodeExtra> workspaceExtras =
context.getExistingExtrasMap().getOrDefault(workspaceUuid, Collections.emptyMap());
for (BatchUpdateWorkspaceExtraReq.WorkspaceExtraItem extraItem : workspaceData.getExtras()) {
String propertyName = extraItem.getPropertyName();
if (StringUtils.isBlank(propertyName)) {
log.warn("[batchUpdateWorkspaceExtra] 工位{}的属性名称为空,跳过", workspaceUuid);
continue;
}
SimulationNodeExtra existingExtra = workspaceExtras.get(propertyName);
boolean isValueEmpty = StringUtils.isBlank(extraItem.getPropertyValue());
SpdmNodeExtraReq nodeExtraReq = new SpdmNodeExtraReq();
nodeExtraReq.setNodeId(workspaceUuid);
nodeExtraReq.setPropertyName(propertyName);
nodeExtraReq.setPropertyValue(isValueEmpty ? null : extraItem.getPropertyValue());
nodeExtraReq.setValueType(StringUtils.isNotBlank(extraItem.getValueType()) ? extraItem.getValueType() : "string");
nodeExtraReq.setPropertyClass(extraItem.getPropertyClass());
if (existingExtra != null) {
nodeExtraReq.setId(existingExtra.getId());
nodeExtraReq.setUpdater(context.getUserContext().getUserId());
nodeExtraReq.setUpdateTime(context.getUserContext().getCurrentTime());
context.getUpdateList().add(nodeExtraReq);
} else if (!isValueEmpty) {
nodeExtraReq.setCreator(context.getUserContext().getUserId());
nodeExtraReq.setCreateTime(context.getUserContext().getCurrentTime());
context.getInsertList().add(nodeExtraReq);
}
}
}
}
/**
* 执行批量操作
*/
private void executeBatchOperations(BatchUpdateContext context) {
if (CollectionUtils.isNotEmpty(context.getUpdateList())) {
for (SpdmNodeExtraReq updateReq : context.getUpdateList()) {
int result = nodeMapper.editNodeExtraWithNull(updateReq);
if (result <= 0) {
throw new IllegalStateException(
String.format("更新扩展属性失败 nodeId=%s, propertyName=%s",
updateReq.getNodeId(), updateReq.getPropertyName()));
}
}
}
if (CollectionUtils.isNotEmpty(context.getInsertList())) {
int result = nodeMapper.addNodeExtraBatch(context.getInsertList());
if (result <= 0) {
throw new IllegalStateException("新增扩展属性失败");
}
}
}
/**
* 批量更新上下文,封装所有相关数据
*/
@Data
private static class BatchUpdateContext {
private final List<BatchUpdateWorkspaceExtraReq.WorkspaceExtraData> workspaceExtrasList;
private final List<String> workspaceUuids;
private final Map<String, Map<String, SimulationNodeExtra>> existingExtrasMap;
private final UserContext userContext;
private final List<SpdmNodeExtraReq> updateList = new ArrayList<>();
private final List<SpdmNodeExtraReq> insertList = new ArrayList<>();
public BatchUpdateContext(List<BatchUpdateWorkspaceExtraReq.WorkspaceExtraData> workspaceExtrasList,
List<String> workspaceUuids,
Map<String, Map<String, SimulationNodeExtra>> existingExtrasMap,
UserContext userContext) {
this.workspaceExtrasList = workspaceExtrasList;
this.workspaceUuids = workspaceUuids;
this.existingExtrasMap = existingExtrasMap;
this.userContext = userContext;
}
}
/**
* 用户上下文,封装用户相关信息
*/
private static class UserContext {
private final Long userId;
private final String currentTime;
public UserContext(Long userId, String currentTime) {
this.userId = userId;
this.currentTime = currentTime;
}
public Long getUserId() {
return userId;
}
public String getCurrentTime() {
return currentTime;
}
}
@Override
public SdmResponse<List<AllNodeByProjectIdAndTypeResp>> getAllNodeByBodeType(String nodeType, Long nodeId) {
try {

View File

@@ -124,6 +124,36 @@
where id = #{nodeExtra.id}
</update>
<update id="editNodeExtraWithNull">
update simulation_node_extra
<trim prefix="set" suffixOverrides=",">
<if test="nodeExtra.propertyName != null and nodeExtra.propertyName != ''">
propertyName = #{nodeExtra.propertyName},
</if>
<choose>
<when test="nodeExtra.propertyValue != null">
propertyValue = #{nodeExtra.propertyValue},
</when>
<otherwise>
propertyValue = null,
</otherwise>
</choose>
<if test="nodeExtra.valueType != null and nodeExtra.valueType != ''">
valueType = #{nodeExtra.valueType},
</if>
<if test="nodeExtra.propertyClass != null and nodeExtra.propertyClass != ''">
propertyClass = #{nodeExtra.propertyClass},
</if>
<if test="nodeExtra.updater != null and nodeExtra.updater != ''">
updater = #{nodeExtra.updater},
</if>
<if test="nodeExtra.updateTime != null and nodeExtra.updateTime != ''">
update_time = #{nodeExtra.updateTime},
</if>
</trim>
where id = #{nodeExtra.id}
</update>
<delete id="deleteNodeBatch">
delete from simulation_node
where uuid in (