Commit 2229af8f authored by LiuLin's avatar LiuLin

fix(ymt):96333和监管顺序码重写

parent fa324116
......@@ -63,4 +63,28 @@
// public ResponseModel<String> createURCode(@RequestParam("key") String key) {
// return ResponseHelper.buildResponse(createCodeService.createUseRegistrationCode(key));
// }
//
// /**
// * 96333顺序码生成
// * @param key key
// * @return String
// */
// @TycloudOperation(ApiLevel = UserType.AGENCY)
// @PostMapping(value = "/elevatorCode")
// @ApiOperation(httpMethod = "POST", value = "96333顺序码生成", notes = "96333顺序码生成")
// public ResponseModel<String> elevatorCode(@RequestParam("key") String key) {
// return ResponseHelper.buildResponse(createCodeService.createElevatorCode(key));
// }
//
// /**
// * 监管顺序码生成
// * @param key key
// * @return String
// */
// @TycloudOperation(ApiLevel = UserType.AGENCY)
// @PostMapping(value = "/sequenceKeyCode")
// @ApiOperation(httpMethod = "POST", value = "监管顺序码生成", notes = "监管顺序码生成")
// public ResponseModel<String> sequenceKeyCode(@RequestParam("key") String key) {
// return ResponseHelper.buildResponse(createCodeService.createSupervisoryCode(key));
// }
//}
......@@ -46,13 +46,19 @@ public enum EquipmentCategoryEnum {
public static Map<String, String> getName = new HashMap<>();
public static Map<String, String> getCode = new HashMap<>();
public static Map<String, String> getValue = new HashMap<>();
private static final Map<String, String> valueToCodeMap = new HashMap<>();
static {
for (EquipmentCategoryEnum e : EquipmentCategoryEnum.values()) {
getName.put(e.code, e.name);
getCode.put(e.value, e.code);
getValue.put(e.value, e.code);
valueToCodeMap.put("96333_"+ e.value, e.getValue() + e.getCode());
}
}
// 根据value获取对应的code
public static String getCodeByValue(String value) {
return valueToCodeMap.get(value);
}
}
......@@ -2,6 +2,7 @@ package com.yeejoin.amos.boot.module.ymt.api.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yeejoin.amos.boot.module.ymt.api.dto.EquInfoDto;
import com.yeejoin.amos.boot.module.ymt.api.dto.KV;
import com.yeejoin.amos.boot.module.ymt.api.entity.CategoryOtherInfo;
import lombok.NonNull;
import org.apache.ibatis.annotations.Param;
......@@ -44,4 +45,16 @@ public interface CategoryOtherInfoMapper extends BaseMapper<CategoryOtherInfo> {
List<Integer> selectExceedElevatorCodeList(Integer start,String prefix);
Integer selectCode(Integer start, Integer end, String prefix);
/**
* 查询96333码,根据区域+类别分组后,取最大顺序码
* @return list
*/
List<KV> selectElevatorCodeMaxValue();
/**
* 查询监管码,根据区域+类别分组后,取最大顺序码
* @return list
*/
List<KV> selectSupervisorCodeMaxValue();
}
......@@ -17,7 +17,6 @@ public interface ICreateCodeService {
*/
List<String> createApplicationFormCode(String type, int batchSize);
/**
* 生成设备注册编码(20位)
* @param key key
......@@ -32,4 +31,24 @@ public interface ICreateCodeService {
*/
String createUseRegistrationCode(String key);
/**
* 96333编码生成(7位)
* @param key key
* @return 96333顺序码
*/
String createElevatorCode(String key);
/**
* 回退顺序码
* @param key redisKey
* @return bool
*/
boolean reduceElevatorCode(String key);
/**
* 监管编码生成(7位)
* @param key key
* @return 7位监管编码生成
*/
String createSupervisoryCode(String key);
}
......@@ -2,6 +2,7 @@ package com.yeejoin.amos.boot.module.ymt.api.service.impl;
import com.yeejoin.amos.boot.module.ymt.api.common.DateUtils;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentCategoryEnum;
import com.yeejoin.amos.boot.module.ymt.api.service.ICreateCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
......@@ -26,7 +27,10 @@ public class CreateCodeServiceImpl implements ICreateCodeService {
private static final String LOCK_KEY_DR = "sequence_lock_dr";
private static final String SEQUENCE_TYPE_DR = "%04d";
private static final String LOCK_KEY_UR = "sequence_lock_ur";
private static final String LOCK_KEY_ELEVATOR = "sequence_lock_elevator";
private static final String LOCK_KEY_SUPERVISORY = "sequence_lock_supervisory";
private static final String SEQUENCE_TYPE_UR = "%05d";
private static final String SEQUENCE_TYPE = "%07d";
private final RedisTemplate<String, String> redisTemplate;
private String rulePrefix;
......@@ -58,7 +62,7 @@ public class CreateCodeServiceImpl implements ICreateCodeService {
*/
@Override
public String createDeviceRegistrationCode(String key) {
return generateSequence(key, SEQUENCE_TYPE_DR, LOCK_KEY_DR);
return (key.length() == 16) ? generateSequence(key, SEQUENCE_TYPE_DR, LOCK_KEY_DR) : "生成码规则不对!";
}
/**
......@@ -73,6 +77,48 @@ public class CreateCodeServiceImpl implements ICreateCodeService {
return generateSequence(key, SEQUENCE_TYPE_UR, LOCK_KEY_UR);
}
@Override
public String createElevatorCode(String key) {
return (key.length() == 8) ? generateElevatorSequence(key, SEQUENCE_TYPE, LOCK_KEY_ELEVATOR) : "生成码规则不对!";
}
@Override
public boolean reduceElevatorCode(String key) {
return reduceSequence(key, SEQUENCE_TYPE, LOCK_KEY_ELEVATOR);
}
@Override
public String createSupervisoryCode(String key) {
return (key.length() == 5) ? generateSupervisorySequence(key) : "生成码规则不对!";
}
private String generateSupervisorySequence(String sequenceKey) {
// 使用分布式锁,确保在并发情况下只有一个线程能够生成顺序码
Boolean lockAcquired = obtainLock(CreateCodeServiceImpl.LOCK_KEY_SUPERVISORY);
if (Boolean.TRUE.equals(lockAcquired)) {
try {
// 获取当前顺序码
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
String currentSequenceStr = valueOps.get(sequenceKey);
// 如果为空,则初始化为0
Long currentSequence = (currentSequenceStr != null) ? Long.parseLong(currentSequenceStr) : 0L;
log.info("===================>获取《{}》当前顺序码:{}<===================", sequenceKey, currentSequenceStr);
currentSequence++;
// 生成顺序码
String formattedSequence = String.format(CreateCodeServiceImpl.SEQUENCE_TYPE, currentSequence);
log.info("===================>更新《{}》顺序码:{}<===================", sequenceKey, formattedSequence);
// 更新顺序码
valueOps.set(sequenceKey, formattedSequence);
return sequenceKey + "-" + formattedSequence;
} finally {
releaseLock(CreateCodeServiceImpl.LOCK_KEY_SUPERVISORY);
}
} else {
throw new RuntimeException("Failed to acquire lock for sequence generation");
}
}
/**
* 校验枚举合法性
*
......@@ -129,7 +175,7 @@ public class CreateCodeServiceImpl implements ICreateCodeService {
}
/**
* 批量生成顺序码
* 生成顺序码
*
* @param sequenceKey redisKey
* @param sequenceType 生成码类型
......@@ -173,6 +219,90 @@ public class CreateCodeServiceImpl implements ICreateCodeService {
}
/**
* 生成顺序码
*
* @param sequenceKey redisKey
* @param sequenceType 生成码类型
* @param lockKey redis锁
* @return s
*/
public String generateElevatorSequence(String sequenceKey, String sequenceType, String lockKey) {
// 使用分布式锁,确保在并发情况下只有一个线程能够生成顺序码
Boolean lockAcquired = obtainLock(lockKey);
if (Boolean.TRUE.equals(lockAcquired)) {
try {
// 获取当前顺序码
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
String currentSequenceStr = valueOps.get(sequenceKey);
// 如果为空,则初始化为0
if (currentSequenceStr == null) {
currentSequenceStr = EquipmentCategoryEnum.getCodeByValue(sequenceKey);
log.info("===================>获取《{}》初始码:{}<===================", sequenceKey, currentSequenceStr);
return currentSequenceStr;
}
Long currentSequence = Long.parseLong(currentSequenceStr);
log.info("===================>获取《{}》当前顺序码:{}<===================", sequenceKey, currentSequenceStr);
currentSequence++;
// 生成顺序码
String formattedSequence = String.format(sequenceType, currentSequence);
log.info("===================>更新《{}》顺序码:{}<===================", sequenceKey, formattedSequence);
// 更新顺序码
valueOps.set(sequenceKey, formattedSequence);
return formattedSequence;
} finally {
releaseLock(lockKey);
}
} else {
throw new RuntimeException("Failed to acquire lock for sequence generation");
}
}
/**
* 回退顺序码
*
* @param sequenceKey redisKey
* @param sequenceType 码类型
* @param lockKey 分布锁
* @return 操作是否成功
*/
public boolean reduceSequence(String sequenceKey, String sequenceType, String lockKey) {
// 使用分布式锁,确保在并发情况下只有一个线程能够生成顺序码
Boolean lockAcquired = obtainLock(lockKey);
if (Boolean.TRUE.equals(lockAcquired)) {
try {
// 获取当前顺序码
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
String currentSequenceStr = valueOps.get(sequenceKey);
// 如果为空,则初始化为0
long currentSequence = (currentSequenceStr != null) ? Long.parseLong(currentSequenceStr) : 0L;
log.info("===================>获取《{}》当前顺序码:{}<===================", sequenceKey, currentSequenceStr);
// 判断是否有可回退的操作
if (currentSequence > 0) {
currentSequence--;
// 生成顺序码
String formattedSequence = String.format(sequenceType, currentSequence);
log.info("===================>回退《{}》顺序码:{}<===================", sequenceKey, formattedSequence);
// 更新顺序码
valueOps.set(sequenceKey, String.valueOf(formattedSequence));
return true; // 回退成功
} else {
log.warn("===================>无法回退《{}》顺序码,当前顺序码已为0<===================", sequenceKey);
return false; // 无法回退,当前顺序码已为0
}
} finally {
releaseLock(lockKey);
}
} else {
throw new RuntimeException("Failed to acquire lock for sequence generation");
}
}
/**
* 分布式锁
*
* @param lockKey lockKey
......
......@@ -33,6 +33,26 @@
<if test="status == 2 ">ORDER BY CODE96333 ASC LIMIT 1 </if>
</select>
<select id="selectElevatorCodeMaxValue" resultType="com.yeejoin.amos.boot.module.ymt.api.dto.KV">
WITH ElevatorResults AS (
SELECT ROW_NUMBER() OVER (PARTITION BY SUBSTRING (CODE96333 FROM 1 FOR 2) ORDER BY CODE96333 DESC) AS row_num,
CODE96333
FROM biz_jg_supervisory_code
WHERE CODE96333 IS NOT NULL AND CODE96333 <![CDATA[<> '']]>)
SELECT '96333_' || SUBSTRING(CODE96333 FROM 1 FOR 2) AS name,
CODE96333 AS value
FROM ElevatorResults WHERE row_num = 1
</select>
<select id="selectSupervisorCodeMaxValue" resultType="com.yeejoin.amos.boot.module.ymt.api.dto.KV">
WITH SupervisorResults AS (
SELECT supervisory_code, ROW_NUMBER() OVER (PARTITION BY SUBSTRING(supervisory_code FROM 1 FOR 5) ORDER BY supervisory_code DESC) AS row_num
FROM biz_jg_supervisory_code WHERE supervisory_code IS NOT NULL AND supervisory_code <![CDATA[<> '')]]>
SELECT SUBSTRING(supervisory_code FROM 1 FOR 5) AS name,
SUBSTRING(supervisory_code FROM 7 FOR 7) AS value
FROM SupervisorResults WHERE row_num = 1
</select>
<select id="selectEquipInfo" resultType="com.yeejoin.amos.boot.module.ymt.api.dto.EquInfoDto">
SELECT "CITY",
"COUNTY",
......
package com.yeejoin.amos.boot.module.ymt.biz.config;
import com.yeejoin.amos.boot.module.ymt.api.dto.KV;
import com.yeejoin.amos.boot.module.ymt.api.mapper.CategoryOtherInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 初始化监管码和96333码
*
* @author LiuLin
* @date 2023年12月15日 17:47
*/
@Component
public class SupervisionCacheInitializer implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(SupervisionCacheInitializer.class);
private final CategoryOtherInfoMapper categoryOtherInfoMapper;
private final StringRedisTemplate stringRedisTemplate;
@Autowired
public SupervisionCacheInitializer(CategoryOtherInfoMapper categoryOtherInfoMapper, StringRedisTemplate stringRedisTemplate) {
this.categoryOtherInfoMapper = categoryOtherInfoMapper;
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public void run(ApplicationArguments args) {
preloadCache(categoryOtherInfoMapper.selectElevatorCodeMaxValue());
preloadCache(categoryOtherInfoMapper.selectSupervisorCodeMaxValue());
log.info(">>>>>>>>>>>>>>>>服务启动执行Redis缓存预加载96333和监管数据完成!>>>>>>>>>>>>>>>>");
}
/**
* 预加载缓存
*
* @param codeList 待加载的代码列表
*/
private void preloadCache(List<KV> codeList) {
codeList.forEach(vo -> stringRedisTemplate.opsForValue().set(vo.getName(), (String) vo.getValue()));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment