Commit f4ee6999 authored by tianyiming's avatar tianyiming

1、一码通96333码空区间问题

2、一码通多线程校验code重复问题
parent 78d24a5d
......@@ -50,7 +50,7 @@ public enum EquipmentCategoryEnum {
static {
for (EquipmentCategoryEnum e : EquipmentCategoryEnum.values()) {
getName.put(e.code, e.name);
getCode.put(e.name, e.code);
getCode.put(e.value, e.code);
getValue.put(e.value, e.code);
}
......
......@@ -6,6 +6,7 @@ import com.yeejoin.amos.boot.module.ymt.api.entity.CategoryOtherInfo;
import lombok.NonNull;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
......@@ -39,4 +40,8 @@ public interface CategoryOtherInfoMapper extends BaseMapper<CategoryOtherInfo> {
@Param("equCode") String equCode,
@Param("useOrgCode") String useOrgCode,
@Param("record") String record);
List<Integer> selectExceedElevatorCodeList(Integer start,String prefix);
Integer selectCode(Integer start, Integer end, String prefix);
}
......@@ -128,4 +128,27 @@
) AS code
</if>
</select>
<select id="selectExceedElevatorCodeList" resultType="java.lang.Integer">
SELECT CODE96333 code
FROM biz_jg_supervisory_code bjsc
WHERE code LIKE CONCAT(#{prefix}, '%')
<if test="start != null and start != ''">
AND code <![CDATA[ >= ]]> #{start}
</if>
ORDER BY code
</select>
<select id="selectCode" resultType="java.lang.Integer">
SELECT
generate_series AS missing_numbers
FROM
generate_series ( #{start}, #{end} )
LEFT JOIN ( SELECT code96333 code FROM biz_jg_supervisory_code WHERE code96333 LIKE CONCAT ( #{prefix}, '%' ) ) asd ON generate_series = asd.code
WHERE
asd.code IS NULL
ORDER BY
generate_series
LIMIT 1
</select>
</mapper>
......@@ -73,6 +73,7 @@ import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static com.alibaba.fastjson.JSON.toJSONString;
......@@ -293,6 +294,21 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
@Autowired
RestHighLevelClient restHighLevelClient;
@Autowired
RedissonClient redissonClient;
//一码通生成码分布式锁key
private final static String LOCK_KEY = "RESOURCE_KEY";
//一码通checkCode分布式锁key
private final static String CHECK_CODE_LOCK_KEY = "CHECK_CODE_KEY";
//一码通checkCode中96333码redis key
private final static String CHECK_CODE_CODE96333 = "CODE96333_";
//一码通checkCode中设备代码redis key
private final static String CHECK_CODE_EQU_CODE = "EQU_CODE_";
//一码通checkCode中使用登记证编号redis key
private final static String CHECK_CODE_USE_ORG_CODE = "USE_ORG_CODE_";
//一码通checkCode中redis key过期时间
private long time = 300l;
private ExecutorService threadPool = Executors.newCachedThreadPool();
/**
......@@ -600,13 +616,52 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
String equCode = ObjectUtils.isEmpty(obj.get("EQU_CODE")) ? null : String.valueOf(obj.get("EQU_CODE"));
String useOrgCode = ObjectUtils.isEmpty(obj.get("USE_ORG_CODE")) ? null : String.valueOf(obj.get("USE_ORG_CODE"));
String record = ObjectUtils.isEmpty(obj.get("id")) ? null : String.valueOf(obj.get("id"));
Map<String, Long> map = categoryOtherInfoMapper.checkCode(type, code96333, equCode, useOrgCode, record);
if (map.containsKey("equCode") && map.get("equCode") > 0) {
result = "设备代码重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else if (map.containsKey("useOrgCode") && map.get("useOrgCode") > 0) {
result = "使用登记证编号重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else if (map.containsKey("code") && map.get("code") > 0) {
result = "96333码重复,请确认数据是否输入正确,或联系管辖机构处理。";
RLock lock = null;
try {
lock = redissonClient.getLock(CHECK_CODE_LOCK_KEY);
if (!ObjectUtils.isEmpty(code96333)) {
if (redisUtils.hasKey(CHECK_CODE_CODE96333 + code96333)) {
redisUtils.del(CHECK_CODE_EQU_CODE + equCode);
redisUtils.del(CHECK_CODE_USE_ORG_CODE + useOrgCode);
return "96333码重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else {
redisUtils.set(CHECK_CODE_CODE96333 + code96333, "1", time);
}
}
if (!ObjectUtils.isEmpty(equCode)) {
if (redisUtils.hasKey(CHECK_CODE_EQU_CODE + equCode)) {
redisUtils.del(CHECK_CODE_CODE96333 + code96333);
redisUtils.del(CHECK_CODE_USE_ORG_CODE + useOrgCode);
return "设备代码重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else {
redisUtils.set(CHECK_CODE_EQU_CODE + equCode, "1", time);
}
}
if (!ObjectUtils.isEmpty(useOrgCode)) {
if (redisUtils.hasKey(CHECK_CODE_USE_ORG_CODE + useOrgCode)) {
redisUtils.del(CHECK_CODE_EQU_CODE + equCode);
redisUtils.del(CHECK_CODE_CODE96333 + code96333);
return "使用登记证编号重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else {
redisUtils.set(CHECK_CODE_USE_ORG_CODE + useOrgCode, "1", time);
}
}
Map<String, Long> map = categoryOtherInfoMapper.checkCode(type, code96333, equCode, useOrgCode, record);
if (map.containsKey("equCode") && map.get("equCode") > 0) {
result = "设备代码重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else if (map.containsKey("useOrgCode") && map.get("useOrgCode") > 0) {
result = "使用登记证编号重复,请确认数据是否输入正确,或联系管辖机构处理。";
} else if (map.containsKey("code") && map.get("code") > 0) {
result = "96333码重复,请确认数据是否输入正确,或联系管辖机构处理。";
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
lock.unlock(); // 释放锁
}
return result;
}
......@@ -631,62 +686,73 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
*/
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public synchronized Map<String, String> creatCode(String city, String county, String equipCategory, String code96333, String supervisionCode) {
Map<String, String> resultMap = new HashMap<>();
StringBuilder supervisorCode = new StringBuilder();
StringBuilder elevatorCode = new StringBuilder();
CategoryOtherInfo categoryOtherInfo = new CategoryOtherInfo();
String prefix;
//判断是否需要生成96333电梯码
if (equipCategory.startsWith("3") && !XIAN.equals(city)) {
//判断数据是否携带96333电梯码,携带则使用,不携带则生成
if ("null".equals(code96333)) {
Map<String, Object> elevatorMap = equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), county);
prefix = ObjectUtils.isEmpty(elevatorMap) ? equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), city).get("code").toString() : elevatorMap.get("code").toString();
//查询未使用的电梯码
categoryOtherInfo = categoryOtherInfoMapper.selectElevatorCode(prefix, EquipmentCategoryEnum.WSY.getCode());
//如果存在未使用的电梯码则启用未使用的否则创建
String elevator = ObjectUtils.isEmpty(categoryOtherInfo) ? createElevatorCode(prefix) : categoryOtherInfo.getCode();
if (!ObjectUtils.isEmpty(categoryOtherInfo)) {
supervisoryCodeInfoMapper.delete(new QueryWrapper<SupervisoryCodeInfo>().eq("code96333", categoryOtherInfo.getCode()));
RLock lock = redissonClient.getLock(LOCK_KEY);
Map<String, String> resultMap = null;
try {
lock.lock(); // 获取锁
log.info("加锁成功");
resultMap = new HashMap<>();
StringBuilder supervisorCode = new StringBuilder();
StringBuilder elevatorCode = new StringBuilder();
CategoryOtherInfo categoryOtherInfo = new CategoryOtherInfo();
String prefix;
//判断是否需要生成96333电梯码
if (equipCategory.startsWith("3") && !XIAN.equals(city)) {
//判断数据是否携带96333电梯码,携带则使用,不携带则生成
if ("null".equals(code96333)) {
Map<String, Object> elevatorMap = equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), county);
prefix = ObjectUtils.isEmpty(elevatorMap) ? equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), city).get("code").toString() : elevatorMap.get("code").toString();
//查询未使用的电梯码
categoryOtherInfo = categoryOtherInfoMapper.selectElevatorCode(prefix, EquipmentCategoryEnum.WSY.getCode());
//如果存在未使用的电梯码则启用未使用的否则创建
String elevator = ObjectUtils.isEmpty(categoryOtherInfo) ? createElevatorCode(prefix) : categoryOtherInfo.getCode();
if (!ObjectUtils.isEmpty(categoryOtherInfo)) {
supervisoryCodeInfoMapper.delete(new QueryWrapper<SupervisoryCodeInfo>().eq("code96333", categoryOtherInfo.getCode()));
}
elevatorCode.append(elevator);
resultMap.put("creatStatus", CREATE);
} else {
elevatorCode.append(code96333);
resultMap.put("creatStatus", NOT_CREATE);
}
elevatorCode.append(elevator);
resultMap.put("creatStatus", CREATE);
}
//判断原数据是否存在监管码,存在则用原监管码即可,不存在则生成
if ("null".equals(supervisionCode)) {
String supervisor = createSupervisorCode(city, county, equipCategory);
supervisorCode.append(supervisor);
} else {
elevatorCode.append(code96333);
resultMap.put("creatStatus", NOT_CREATE);
supervisorCode = new StringBuilder(supervisionCode);
}
}
//判断原数据是否存在监管码,存在则用原监管码即可,不存在则生成
if ("null".equals(supervisionCode)) {
String supervisor = createSupervisorCode(city, county, equipCategory);
supervisorCode.append(supervisor);
} else {
supervisorCode = new StringBuilder(supervisionCode);
}
if (ObjectUtils.isEmpty(supervisorCode) && ObjectUtils.isEmpty(elevatorCode)) {
return new HashMap<>();
if (ObjectUtils.isEmpty(supervisorCode) && ObjectUtils.isEmpty(elevatorCode)) {
return new HashMap<>();
}
log.info("生成码成功");
SupervisoryCodeInfo supervisoryCodeInfo = new SupervisoryCodeInfo();
SupervisoryCodeInfo selectOne = supervisoryCodeInfoMapper.selectOne(new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", supervisionCode));
//将生成的码添加到码表中,码的使用状态为初始状态
String equState = EquipmentCategoryEnum.CSZT.getCode();
supervisoryCodeInfo.setCode96333(String.valueOf(elevatorCode));
supervisoryCodeInfo.setCreateStatus(resultMap.get("creatStatus"));
supervisoryCodeInfo.setSupervisoryCode(String.valueOf(supervisorCode));
supervisoryCodeInfo.setStatus(equState);
if (ObjectUtils.isEmpty(selectOne)) {
supervisoryCodeInfoMapper.insert(supervisoryCodeInfo);
} else {
selectOne.setCode96333(String.valueOf(elevatorCode));
supervisoryCodeInfoMapper.update(selectOne,
new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", selectOne.getSupervisoryCode()));
}
//使用UUID生成一个record,多表关联关系用
resultMap.put("superviseCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
resultMap.put("code96333", ObjectUtils.isEmpty(elevatorCode) ? null : elevatorCode.toString());
resultMap.put("qrCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
lock.unlock(); // 释放锁
log.info("释放锁");
}
SupervisoryCodeInfo supervisoryCodeInfo = new SupervisoryCodeInfo();
SupervisoryCodeInfo selectOne = supervisoryCodeInfoMapper.selectOne(new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", supervisionCode));
//将生成的码添加到码表中,码的使用状态为初始状态
String equState = EquipmentCategoryEnum.CSZT.getCode();
supervisoryCodeInfo.setCode96333(String.valueOf(elevatorCode));
supervisoryCodeInfo.setCreateStatus(resultMap.get("creatStatus"));
supervisoryCodeInfo.setSupervisoryCode(String.valueOf(supervisorCode));
supervisoryCodeInfo.setStatus(equState);
if (ObjectUtils.isEmpty(selectOne)) {
supervisoryCodeInfoMapper.insert(supervisoryCodeInfo);
} else {
selectOne.setCode96333(String.valueOf(elevatorCode));
supervisoryCodeInfoMapper.update(selectOne,
new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", selectOne.getSupervisoryCode()));
}
//使用UUID生成一个record,多表关联关系用
resultMap.put("superviseCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
resultMap.put("code96333", ObjectUtils.isEmpty(elevatorCode) ? null : elevatorCode.toString());
resultMap.put("qrCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
return resultMap;
}
......@@ -746,22 +812,66 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
//获取行政区划区县、市是否存在历史96333电梯码
CategoryOtherInfo elevatorOtherInfo = categoryOtherInfoMapper.selectElevatorCode(elevatorCode.toString(), null);
if (!ObjectUtils.isEmpty(elevatorOtherInfo) && elevatorOtherInfo.getCode() != null) {
//获取补零位长度
String elevatorCode1 = elevatorOtherInfo.getCode().substring(2);
long num = Long.parseLong(elevatorCode1) + 1;
int numLength = String.valueOf(num).length();
int a = 5 - numLength;
StringBuilder zero = new StringBuilder();
for (int i = 0; i < a; i++) {
zero.append(EquipmentCategoryEnum.BLW.getCode());
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Integer start = Integer.valueOf(prefix + EquipmentCategoryEnum.getCode.get(prefix));
Integer end = Integer.valueOf(elevatorOtherInfo.getCode());
List<Integer> allCodeList = IntStream.rangeClosed(start, end)
.boxed()
.collect(Collectors.toList());
List<Integer> codeList = categoryOtherInfoMapper.selectExceedElevatorCodeList(start, prefix);
List<Integer> resultList = getDiffrent(allCodeList, codeList);
if(!ObjectUtils.isEmpty(resultList)){
elevatorCode.setLength(0);
elevatorCode.append(resultList.get(0));
} else {
//获取补零位长度
String elevatorCode1 = elevatorOtherInfo.getCode().substring(2);
long num = Long.parseLong(elevatorCode1) + 1;
int numLength = String.valueOf(num).length();
int a = 5 - numLength;
StringBuilder zero = new StringBuilder();
for (int i = 0; i < a; i++) {
zero.append(EquipmentCategoryEnum.BLW.getCode());
}
zero.append(num);
elevatorCode.append(zero);
}
zero.append(num);
elevatorCode.append(zero);
stopWatch.stop();
}
}
return elevatorCode.toString();
}
/**
* 获取两个List的不同元素
* @param list1
* @param list2
* @return
*/
private static List<Integer> getDiffrent(List<Integer> list1, List<Integer> list2) {
List<Integer> diff = new ArrayList<Integer>();
Map<Integer, Integer> map = new HashMap<Integer, Integer>(list1.size());
for (Integer integer : list1) {
map.put(integer, 1);
}
for (Integer integer : list2) {
if (map.get(integer) != null) {
map.put(integer, 2);
continue;
}
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() == 1) {
diff.add(entry.getKey());
}
}
// 对集合进行排序
Collections.sort(diff);
return diff;
}
/**
* 获取当前登录人单位类型
......@@ -1329,11 +1439,6 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
return records;
}
@Autowired
RedissonClient redissonClient;
private final static String LOCK_KEY = "RESOURCE_KEY";
@Override
@Transactional(rollbackFor = Exception.class)
public ResponseModel submit(Map<String, Object> map) {
......@@ -1351,7 +1456,12 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
String record = null;
LinkedHashMap superviseMap = (LinkedHashMap) map.get("data");
String equCategory = String.valueOf(superviseMap.get("equCategory"));
String useOrgCode = null;
String equCode = null;
// String alias = String.valueOf(supervisionMap.get("ALIAS"));
// if(){
//
// }
try {
String claimStatus = String.valueOf(superviseMap.get("claimStatus"));
String code96333 = String.valueOf(superviseMap.get("code96333"));
......@@ -1366,15 +1476,7 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
String supervisionCode = String.valueOf(superviseMap.get("supervisionCode"));
EquipmentCategoryServiceImpl categoryService = (EquipmentCategoryServiceImpl) AopContext.currentProxy();
//生成码
//集群模式使用
RLock lock = redissonClient.getLock(LOCK_KEY);
lock.lock(); // 获取锁
log.info("加锁成功");
codeMap = categoryService.creatCode(city, county, equCategory, code96333, supervisionCode);
log.info("生成码成功");
lock.unlock(); // 释放锁
log.info("释放锁");
log.info("已生成对应监管码或96333电梯识别码");
//删除map中的冗余数据,添加对应监管码和96333码调用idx多表单页提交接口吧保存数据
map.remove("data");
supervisionMap.put("CODE96333", codeMap.get("code96333"));
......@@ -1395,7 +1497,7 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.YSY.getCode());
} else {
equipmentCategoryMapper.updateIsNotEs(String.valueOf(supervisionMap.get("SUPERVISORY_CODE")));
supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.BF.getCode());
supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.WSY.getCode());
}
} else if (EquipmentCategoryEnum.DRL.getName().equals(claimStatus)) {
supervisionMap.put("CODE96333", "null".equals(code96333) ? null : code96333);
......@@ -1425,7 +1527,6 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
log.info("已生成对应监管码" + supervisionMap.get("SUPERVISORY_CODE"));
log.info("已生成对应96333电梯识别码" + supervisionMap.get("CODE96333"));
}
supervisoryCodeInfoMapper.update(supervisoryCodeInfo, new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", supervisionMap.get("SUPERVISORY_CODE")));
saveEsElevator2ES(finalRecord);
});
} catch (Exception e) {
......@@ -1437,13 +1538,18 @@ public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryD
superviseInfoMapper.deleteDataAll(records);
esEquipmentCategory.deleteById(record);
}
supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.BF.getCode());
supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.WSY.getCode());
ResponseModel<Object> response = new ResponseModel<>();
response.setDevMessage(e.getMessage());
response.setResult(null);
response.setMessage("操作失败,请检查数据输入后重新提交");
response.setStatus(HttpStatus.BAD_REQUEST.value());
return response;
} finally {
redisUtils.del(CHECK_CODE_USE_ORG_CODE + useOrgCode);
redisUtils.del(CHECK_CODE_EQU_CODE + equCode);
redisUtils.del(CHECK_CODE_CODE96333 + supervisionMap.get("CODE96333"));
supervisoryCodeInfoMapper.update(supervisoryCodeInfo, new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", supervisionMap.get("SUPERVISORY_CODE")));
}
return ResponseHelper.buildResponse(record);
}
......
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