Commit 5968c962c8cb563f4847a3846d4de5b38baf9305

Authored by 颜惠青
2 parents 70d77911 8212d7c2

Merge branch 'dev' of http://gitlab1.renniting.cn/JCSS/urbanops into dev

urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/problemtype/GardenProblemTypeMapper.java
@@ -6,6 +6,8 @@ import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX; @@ -6,6 +6,8 @@ import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX;
6 import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO; 6 import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO;
7 import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; 7 import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
  9 +import org.apache.ibatis.annotations.Param;
  10 +import org.apache.ibatis.annotations.Select;
9 11
10 import java.util.ArrayList; 12 import java.util.ArrayList;
11 import java.util.List; 13 import java.util.List;
@@ -63,25 +65,55 @@ public interface GardenProblemTypeMapper extends BaseMapperX<GardenProblemTypeDO @@ -63,25 +65,55 @@ public interface GardenProblemTypeMapper extends BaseMapperX<GardenProblemTypeDO
63 } 65 }
64 66
65 /** 67 /**
  68 + * 根据名称、父级编码、层级查询记录(校验名称在同级下唯一)
  69 + * 使用 LIMIT 1 避免已有脏数据导致 TooManyResultsException
  70 + */
  71 + default GardenProblemTypeDO selectByNameAndParentAndLevel(String typeName, String parentCode, Integer level) {
  72 + return selectOne(new LambdaQueryWrapperX<GardenProblemTypeDO>()
  73 + .eq(GardenProblemTypeDO::getTypeName, typeName)
  74 + .eq(GardenProblemTypeDO::getParentCode, parentCode)
  75 + .eq(GardenProblemTypeDO::getLevel, level)
  76 + .last("LIMIT 1"));
  77 + }
  78 +
  79 + /**
  80 + * 绕过逻辑删除,直接查 typeCode 是否物理存在(用于编码生成时避免唯一键冲突)
  81 + */
  82 + @Select("SELECT COUNT(1) FROM garden_problem_type WHERE type_code = #{code}")
  83 + int countByTypeCodeRaw(@Param("code") String code);
  84 +
  85 + /**
66 * 生成下一个编码:父级编码 + 5位递增序号 86 * 生成下一个编码:父级编码 + 5位递增序号
67 * 如 parentCode=BIZ_GARDEN → BIZ_GARDEN00001, BIZ_GARDEN00002 87 * 如 parentCode=BIZ_GARDEN → BIZ_GARDEN00001, BIZ_GARDEN00002
  88 + * 注意:加 LENGTH 条件避免匹配到子级编码;绕过逻辑删除检查确保唯一键可用
68 */ 89 */
69 default String generateNextCode(String parentCode) { 90 default String generateNextCode(String parentCode) {
  91 + int expectedLength = parentCode.length() + 5;
70 List<GardenProblemTypeDO> list = selectList(new LambdaQueryWrapperX<GardenProblemTypeDO>() 92 List<GardenProblemTypeDO> list = selectList(new LambdaQueryWrapperX<GardenProblemTypeDO>()
71 .likeRight(GardenProblemTypeDO::getTypeCode, parentCode) 93 .likeRight(GardenProblemTypeDO::getTypeCode, parentCode)
  94 + .apply("LENGTH(type_code) = {0}", expectedLength)
72 .orderByDesc(GardenProblemTypeDO::getTypeCode) 95 .orderByDesc(GardenProblemTypeDO::getTypeCode)
73 .last("LIMIT 1")); 96 .last("LIMIT 1"));
  97 + int seq;
74 if (list == null || list.isEmpty()) { 98 if (list == null || list.isEmpty()) {
75 - return parentCode + "00001";  
76 - }  
77 - String maxCode = list.get(0).getTypeCode();  
78 - String seqStr = maxCode.substring(parentCode.length());  
79 - try {  
80 - int seq = Integer.parseInt(seqStr) + 1;  
81 - return parentCode + String.format("%05d", seq);  
82 - } catch (NumberFormatException e) {  
83 - return parentCode + "00001"; 99 + seq = 1;
  100 + } else {
  101 + String maxCode = list.get(0).getTypeCode();
  102 + String seqStr = maxCode.substring(parentCode.length());
  103 + try {
  104 + seq = Integer.parseInt(seqStr) + 1;
  105 + } catch (NumberFormatException e) {
  106 + seq = 1;
  107 + }
84 } 108 }
  109 + // 跳过被逻辑删除记录占用的编码
  110 + int maxAttempts = 100;
  111 + String nextCode;
  112 + do {
  113 + nextCode = parentCode + String.format("%05d", seq);
  114 + seq++;
  115 + } while (countByTypeCodeRaw(nextCode) > 0 && --maxAttempts > 0);
  116 + return nextCode;
85 } 117 }
86 118
87 } 119 }
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/enums/ErrorCodeConstants.java
@@ -150,6 +150,7 @@ public interface ErrorCodeConstants { @@ -150,6 +150,7 @@ public interface ErrorCodeConstants {
150 // ========== 问题类型配置 1-100-009-000 ========== 150 // ========== 问题类型配置 1-100-009-000 ==========
151 ErrorCode PROBLEM_TYPE_NOT_EXISTS = new ErrorCode(1100009000, "问题类型不存在"); 151 ErrorCode PROBLEM_TYPE_NOT_EXISTS = new ErrorCode(1100009000, "问题类型不存在");
152 ErrorCode PROBLEM_TYPE_CODE_EXISTS = new ErrorCode(1100009001, "问题类型编码已存在"); 152 ErrorCode PROBLEM_TYPE_CODE_EXISTS = new ErrorCode(1100009001, "问题类型编码已存在");
  153 + ErrorCode PROBLEM_TYPE_NAME_DUPLICATE = new ErrorCode(1100009002, "同级下问题类型名称已存在,一级、二级、三级类型名称不能同时重复");
153 154
154 // ========== 一树一档案巡检与风险评估 1-100-008-000 ========== 155 // ========== 一树一档案巡检与风险评估 1-100-008-000 ==========
155 ErrorCode TREE_INSPECTION_NOT_EXISTS = new ErrorCode(1100008001, "巡检评估记录不存在"); 156 ErrorCode TREE_INSPECTION_NOT_EXISTS = new ErrorCode(1100008001, "巡检评估记录不存在");
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/problemtype/GardenProblemTypeServiceImpl.java
@@ -13,6 +13,7 @@ import jakarta.annotation.Resource; @@ -13,6 +13,7 @@ import jakarta.annotation.Resource;
13 import java.util.ArrayList; 13 import java.util.ArrayList;
14 import java.util.List; 14 import java.util.List;
15 import java.util.Map; 15 import java.util.Map;
  16 +import java.util.Objects;
16 import java.util.stream.Collectors; 17 import java.util.stream.Collectors;
17 18
18 import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; 19 import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
@@ -43,6 +44,9 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService { @@ -43,6 +44,9 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService {
43 public Long createProblemType(ProblemTypeSaveReqVO createReqVO) { 44 public Long createProblemType(ProblemTypeSaveReqVO createReqVO) {
44 // 校验编码唯一性 45 // 校验编码唯一性
45 validateTypeCodeUnique(createReqVO.getTypeCode(), null); 46 validateTypeCodeUnique(createReqVO.getTypeCode(), null);
  47 + // 校验名称在同级父节点下唯一
  48 + validateTypeNameUniqueUnderParent(createReqVO.getTypeName(),
  49 + createReqVO.getParentCode(), createReqVO.getLevel(), null);
46 // 插入 50 // 插入
47 GardenProblemTypeDO problemType = BeanUtils.toBean(createReqVO, GardenProblemTypeDO.class); 51 GardenProblemTypeDO problemType = BeanUtils.toBean(createReqVO, GardenProblemTypeDO.class);
48 gardenProblemTypeMapper.insert(problemType); 52 gardenProblemTypeMapper.insert(problemType);
@@ -81,6 +85,15 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService { @@ -81,6 +85,15 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService {
81 } 85 }
82 } 86 }
83 87
  88 + private void validateTypeNameUniqueUnderParent(String typeName, String parentCode,
  89 + Integer level, Long excludeId) {
  90 + GardenProblemTypeDO exist = gardenProblemTypeMapper.selectByNameAndParentAndLevel(
  91 + typeName, parentCode, level);
  92 + if (exist != null && (excludeId == null || !exist.getId().equals(excludeId))) {
  93 + throw exception(PROBLEM_TYPE_NAME_DUPLICATE);
  94 + }
  95 + }
  96 +
84 @Override 97 @Override
85 public GardenProblemTypeDO getProblemType(Long id) { 98 public GardenProblemTypeDO getProblemType(Long id) {
86 return gardenProblemTypeMapper.selectById(id); 99 return gardenProblemTypeMapper.selectById(id);
@@ -186,6 +199,10 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService { @@ -186,6 +199,10 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService {
186 entity.setStatus(CommonStatusEnum.ENABLE.getStatus()); 199 entity.setStatus(CommonStatusEnum.ENABLE.getStatus());
187 gardenProblemTypeMapper.insert(entity); 200 gardenProblemTypeMapper.insert(entity);
188 count++; 201 count++;
  202 + } else if (!Objects.equals(exist.getTypeName(), dict.getLabel())) {
  203 + exist.setTypeName(dict.getLabel());
  204 + gardenProblemTypeMapper.updateById(exist);
  205 + count++;
189 } 206 }
190 } 207 }
191 return count; 208 return count;