1、新增 待选转加工、新增加工配置接口名称序列累计能力;2、移除覆盖设置接口;3、装配设置删除接口支持删除导入状态;

This commit is contained in:
gaoqr
2026-03-05 16:17:56 +08:00
parent cd3e654a5e
commit fec25f10ca
11 changed files with 185 additions and 88 deletions
@@ -370,7 +370,7 @@ public class ErrorCodeConstants {
public static final ErrorCode ASSEMBLY_CONFIG_IMPORT_ORDER_COMPONENTS_QUERY_ERROR = new ErrorCode(1_002_050_001, "assembly.config.import.order_components.query.error");
public static final ErrorCode ASSEMBLY_CONFIG_NOT_EXIST = new ErrorCode(1_002_050_002, "assembly.config.not_exist");
public static final ErrorCode ASSEMBLY_CONFIG_DO_CONFIG_EXIST = new ErrorCode(1_002_050_003, "assembly.config.do_config_exist");
public static final ErrorCode ASSEMBLY_CONFIG_COVER_TARGET_NOT_EXIST = new ErrorCode(1_002_050_004, "assembly.config.cover_target_not_exist");
public static final ErrorCode ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST = new ErrorCode(1_002_050_005, "assembly.config.new_config_name_exist");
public static final ErrorCode ASSEMBLY_CONFIG_REMOVE_NOT_EXIST = new ErrorCode(1_002_050_006, "assembly.config.remove_not_exist");
public static final ErrorCode ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST = new ErrorCode(1_002_050_004, "assembly.config.new_config_name_exist");
public static final ErrorCode ASSEMBLY_CONFIG_SAVE_TOPNAME_EXIST = new ErrorCode(1_002_050_005, "assembly.config.save_topname_exist");
public static final ErrorCode ASSEMBLY_CONFIG_NO_NEED_NEW_CONFIG = new ErrorCode(1_002_050_006, "assembly.config.no_need_new_config");
}
@@ -13,6 +13,7 @@ import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -66,14 +67,6 @@ public class AssemblyConfigController {
return CommonResult.success(true);
}
@PostMapping("/cover/{configId}")
@Operation(summary = "覆盖原有加工部件")
@Parameter(name = "configId", description = "装配设置编号", required = true)
public CommonResult<Boolean> coverConfig(@PathVariable Long configId) {
assemblyConfigService.coverConfig(configId);
return CommonResult.success(true);
}
@PostMapping("/new/{configId}")
@Operation(summary = "新增加工部件")
@Parameter(name = "configId", description = "装配设置编号", required = true)
@@ -83,11 +76,11 @@ public class AssemblyConfigController {
return CommonResult.success(true);
}
@PostMapping("/configured/remove/{configId}")
@DeleteMapping("/{configId}")
@Operation(summary = "删除已配置的加工部件,恢复到待选")
@Parameter(name = "configId", description = "装配设置编号", required = true)
public CommonResult<Boolean> removeConfigured(@PathVariable Long configId) {
assemblyConfigService.removeConfigured(configId);
assemblyConfigService.delete(configId);
return CommonResult.success(true);
}
@@ -52,10 +52,15 @@ public class AssemblyConfigDO extends BaseDO {
private String structureHash;
/**
* 件名称
* 件名称
*/
private String componentName;
/**
* 原始部件名称
*/
private String baseName;
/**
* 状态
*/
@@ -0,0 +1,36 @@
package com.cf.imes.module.system.dal.dataobject.assemblyconfig;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author Gqr
* @since 2026/3/5 14:23
*/
@TableName(value = "system_config_assembly_name_seq")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AssemblyConfigNameSeqDO {
/**
* 组织ID
*/
@TableId
private Long organId;
/**
* 部件名称
*/
@TableId
private String baseName;
/**
* 下一个编号
*/
private Integer nextNo;
}
@@ -0,0 +1,20 @@
package com.cf.imes.module.system.dal.mysql.assemblyconfig;
import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigNameSeqDO;
import org.apache.ibatis.annotations.Mapper;
/**
*
*
* @author Gqr
* @since 2026/3/5 14:29
*/
@Mapper
public interface AssemblyConfigNameSeqMapper {
/**
* 生成下一个序号
* 原子操作:如果记录不存在自动插入,存在则 +1
*
*/
int nextSeq(AssemblyConfigNameSeqDO nameSeqDO);
}
@@ -43,13 +43,6 @@ public interface AssemblyConfigService {
*/
void doConfig(Long configId);
/**
* 覆盖原有加工部件
*
* @param configId
*/
void coverConfig(Long configId);
/**
* 新增加工部件
*
@@ -63,7 +56,7 @@ public interface AssemblyConfigService {
*
* @param configId
*/
void removeConfigured(Long configId);
void delete(Long configId);
/**
* 保存装配设置
@@ -2,6 +2,7 @@ package com.cf.imes.module.system.service.assemblyconfig;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -11,6 +12,7 @@ import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.executor.api.ordercomponent.OrderComponentApi;
import com.cf.imes.module.executor.api.ordercomponent.dto.OrderComponentListReqDTO;
@@ -22,11 +24,12 @@ import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConf
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigSaveStructureVO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigStructureVO;
import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigDO;
import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigNameSeqDO;
import com.cf.imes.module.system.dal.mysql.assemblyconfig.AssemblyConfigMapper;
import com.cf.imes.module.system.dal.mysql.assemblyconfig.AssemblyConfigNameSeqMapper;
import com.cf.imes.module.system.enums.assemblyconfig.AssemblyConfigStatusEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,12 +41,12 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_COVER_TARGET_NOT_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_DO_CONFIG_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_IMPORT_ORDER_COMPONENTS_QUERY_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NOT_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_REMOVE_NOT_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NO_NEED_NEW_CONFIG;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_SAVE_TOPNAME_EXIST;
/**
* 装配设置 ServiceImpl 接口实现类
@@ -60,6 +63,9 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
@Resource
private AssemblyConfigMapper assemblyConfigMapper;
@Resource
private AssemblyConfigNameSeqMapper assemblyConfigNameSeqMapper;
@Override
public void importAssemblyConfigFromOrders(AssemblyConfigImportReqVO reqVO) {
Long organId = SecurityFrameworkUtils.getUserOrganId();
@@ -73,7 +79,7 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
}
List<OrderComponentListRespDTO> orderComponentList = orderComponentListResult.getData();
if(CollUtil.isEmpty(orderComponentList)) {
if (CollUtil.isEmpty(orderComponentList)) {
return;
}
// 2、构建树 + 排序 + 生成结构hash
@@ -126,6 +132,7 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
configDO.setOrganId(organId);
configDO.setSourceComponentId(node.getSourceComponentId());
configDO.setComponentName(node.getName());
configDO.setBaseName(node.getName());
configDO.setStructureHash(node.getStructureHash());
configDO.setStructureJson(JsonUtils.zipString(JsonUtils.toJsonString(node)));
configDO.setStatus(AssemblyConfigStatusEnum.IMPORT.getStatus());
@@ -282,6 +289,9 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
// 1、校验本身
AssemblyConfigDO assemblyConfigDO = getById(configId, organId);
String componentName = assemblyConfigDO.getComponentName();
if (ObjectUtil.equals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus())) {
return;
}
// 2、校验本身以外是否还有重名的顶级部件设置
boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
@@ -293,42 +303,8 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
);
AssertUtils.isTrue(exists, ASSEMBLY_CONFIG_DO_CONFIG_EXIST, componentName);
// 3、更新状态
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void coverConfig(Long configId) {
Long organId = SecurityFrameworkUtils.getUserOrganId();
// 1、校验本身
AssemblyConfigDO assemblyConfigDO = getById(configId, organId);
// 2、校验要覆盖的目标是否存在
boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getComponentName, assemblyConfigDO.getComponentName())
.ne(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
AssertUtils.isFalse(exists, ASSEMBLY_CONFIG_COVER_TARGET_NOT_EXIST);
// 3、把原来同名的改为导入
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getComponentName, assemblyConfigDO.getComponentName())
.ne(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
);
// 3、生成序号 seq(直接使用 componentName 作为 baseName
nextSeq(organId, componentName);
// 4、更新状态
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
@@ -353,35 +329,76 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
AssertUtils.isTrue(exists, ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST, name);
// 4、更新状态和名称
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.set(AssemblyConfigDO::getComponentName, name)
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
if (exists) {
// 重名 → 自动生成新名字
// seq 表里直接用 newName 作为 baseName
int seq = nextSeq(organId, name);
String newName = name + " " + seq;
// 再次校验生成的新名字是否意外重复
boolean newExists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getComponentName, newName)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
AssertUtils.isTrue(newExists, ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST, name);
// 4、更新状态和名称
assemblyConfigMapper.update(new LambdaUpdateWrapperX<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.setIfPresent(AssemblyConfigDO::getComponentName, newName)
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
} else {
throw new ServiceException(ASSEMBLY_CONFIG_NO_NEED_NEW_CONFIG, name);
}
}
/**
* 获取下一个编号
*
* @param organId
* @param baseName
* @return
*/
public int nextSeq(Long organId, String baseName) {
AssemblyConfigNameSeqDO assemblyConfigNameSeqDO = new AssemblyConfigNameSeqDO(organId, baseName, null);
assemblyConfigNameSeqMapper.nextSeq(assemblyConfigNameSeqDO);// 插入或更新 seq 表
return assemblyConfigNameSeqDO.getNextNo() - 1; // 真正返回 seq
}
@Override
public void removeConfigured(Long configId) {
public void delete(Long configId) {
Long organId = SecurityFrameworkUtils.getUserOrganId();
// 1、校验本身
AssemblyConfigDO assemblyConfigDO = getById(configId, organId);
// 2、校验状态
AssertUtils.notEquals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus(), ASSEMBLY_CONFIG_REMOVE_NOT_EXIST);
// 3、更新状态
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
);
// 2、根据状态走不同的删除
if (ObjectUtil.equals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus())) {
// 已配置的改成导入
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
);
} else {
// 导入状态的删除
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, configId)
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.set(AssemblyConfigDO::getDeleted, DeletedCodeEnum.DELETED.getStatus())
.set(AssemblyConfigDO::getComponentName, assemblyConfigDO.getBaseName())
);
}
}
@Override
@@ -390,18 +407,34 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService {
// 1、校验本身
AssemblyConfigDO assemblyConfigDO = getById(reqVO.getId(), organId);
// 2、更新hash和json
AssemblyConfigSaveStructureVO config = reqVO.getConfig();
AssemblyConfigSaveStructureVO config = reqVO.getConfig();
AssemblyConfigStructureVO structureVO = BeanUtil.toBean(config, AssemblyConfigStructureVO.class);
String newTopName = structureVO.getName();
// 2、如果顶级的名称发生改变,需要校验是否重复,并且同步给name
String needChangeName = null;
if (!assemblyConfigDO.getComponentName().equals(newTopName)) {
boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getComponentName, newTopName)
.ne(AssemblyConfigDO::getId, assemblyConfigDO.getId())
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
);
AssertUtils.isTrue(exists, ASSEMBLY_CONFIG_SAVE_TOPNAME_EXIST, newTopName);
needChangeName = newTopName;
}
// 3、更新hash和json
computeHashRecursively(structureVO);
String structureHash = structureVO.getStructureHash();
assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
assemblyConfigMapper.update(new LambdaUpdateWrapperX<AssemblyConfigDO>()
.eq(AssemblyConfigDO::getId, assemblyConfigDO.getId())
.eq(AssemblyConfigDO::getOrganId, organId)
.eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
.eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
.setIfPresent(AssemblyConfigDO::getComponentName, needChangeName)
.set(AssemblyConfigDO::getStructureHash, structureHash)
.set(AssemblyConfigDO::getStructureJson, JsonUtils.zipString(JsonUtils.toJsonString(config)))
);
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cf.imes.module.system.dal.mysql.assemblyconfig.AssemblyConfigNameSeqMapper">
<!-- 1. 原子生成序号 -->
<insert id="nextSeq"
useGeneratedKeys="true"
keyProperty="nextNo"
keyColumn="nextNo">
INSERT INTO system_config_assembly_name_seq(organ_id, base_name, next_no)
VALUES (#{organId}, #{baseName}, LAST_INSERT_ID(1))
ON DUPLICATE KEY UPDATE next_no = LAST_INSERT_ID(next_no + 1)
</insert>
</mapper>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long