Commit 15f03222 authored by LiuLin's avatar LiuLin

fix(ymt):顺序码service实现类删除,改用Feign调用

parent 6e004f22
......@@ -13,12 +13,12 @@ import com.yeejoin.amos.boot.module.jg.api.mapper.JgEquipTransferEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgEquipTransferMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IJgEquipTransferService;
import com.yeejoin.amos.boot.module.jg.api.dto.JgEquipTransferDto;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.ymt.api.common.BaseException;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.OtherInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.RegistrationInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.service.ICreateCodeService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.workflow.Workflow;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowBatchDTO;
......@@ -36,6 +36,7 @@ import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
......@@ -54,9 +55,6 @@ public class JgEquipTransferServiceImpl extends BaseService<JgEquipTransferDto,J
private static final String SUBMIT_TYPE_FLOW = "1";
@Autowired
private ICreateCodeService iCreateCodeService;
@Autowired
JgEquipTransferEqMapper jgEquipTransferEqMapper;
@Autowired
......@@ -68,6 +66,9 @@ public class JgEquipTransferServiceImpl extends BaseService<JgEquipTransferDto,J
@Autowired
RedisUtils redisUtils;
@Autowired
TzsServiceFeignClient tzsServiceFeignClient;
@Transactional(rollbackFor = {Exception.class, BaseException.class})
public void saveOrUpdateModel(String submitType, JgEquipTransferDto model, ReginParams reginParams) {
String[] taskName = new String[]{"流程结束"};
......@@ -80,8 +81,8 @@ public class JgEquipTransferServiceImpl extends BaseService<JgEquipTransferDto,J
}
// 获取设备移交顺序号
List<String> applyNoList = iCreateCodeService.createApplicationFormCode(ApplicationFormTypeEnum.SBYJ.getCode(), deviceList.size());
if (CollectionUtils.isEmpty(applyNoList)) {
ResponseModel<List<String>> responseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.SBYJ.getCode(), deviceList.size());
if (CollectionUtils.isEmpty(responseModel.getResult())) {
return;
}
ArrayList<String> roleListFirst = new ArrayList<>();
......@@ -150,7 +151,7 @@ public class JgEquipTransferServiceImpl extends BaseService<JgEquipTransferDto,J
JgEquipTransfer dto = new JgEquipTransfer();
BeanUtils.copyProperties(model, dto);
int i = deviceList.indexOf(obj);
String applyNo = applyNoList.get(i);
String applyNo = responseModel.getResult().get(i);
dto.setApplyNo(applyNo);
dto.setApplyDate(new Date());
......
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;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author LiuLin
* @date 2023-12-14
*/
@Slf4j
@Service
public class CreateCodeServiceImpl implements ICreateCodeService {
private static final String LOCK_VALUE = "locked";
private static final String LOCK_KEY_AF = "sequence_lock_af";
private static final String SEQUENCE_TYPE_AF = "%03d";
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 = "";
public CreateCodeServiceImpl(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 生成申请单编号(13位,GZ20231214000)
*
* @param type 枚举类型
* @param batchSize 生成个数
* @return List
*/
@Override
public List<String> createApplicationFormCode(String type, int batchSize) {
if (!isValueInEnum(type)) {
return Collections.emptyList();
}
rulePrefix = type + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
return generateBatchSequence(type, batchSize);
}
/**
* 生成设备注册编码(20位)
*
* @param key key
* @return 顺序编号
*/
@Override
public String createDeviceRegistrationCode(String key) {
return (key.length() == 16) ? generateSequence(key, SEQUENCE_TYPE_DR, LOCK_KEY_DR) : "生成码规则不对!";
}
/**
* 生成使用登记证编号(13位,起11陕C00001(23))
*
* @param key key
* @return 顺序编号
*/
@Override
public String createUseRegistrationCode(String key) {
rulePrefix = "(" + LocalDate.now().format(DateTimeFormatter.ofPattern("yy")) + ")";
return (key.length() == 5) ?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");
}
}
/**
* 校验枚举合法性
*
* @param value value
* @return bool
*/
public boolean isValueInEnum(String value) {
return EnumSet.allOf(ApplicationFormTypeEnum.class)
.stream()
.anyMatch(enumValue -> enumValue.name().equals(value));
}
/**
* 批量生成顺序码
*
* @param sequenceKey sequenceKey
* @param batchSize 批量生成个数
* @return List
*/
public List<String> generateBatchSequence(String sequenceKey, int batchSize) {
// 使用分布式锁,确保在并发情况下只有一个线程能够生成顺序码
Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY_AF, LOCK_VALUE);
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);
// 生成批量顺序码
List<String> sequenceList = new ArrayList<>();
log.info("===================>批量生成{}个《{}》顺序码<===================", batchSize, sequenceKey);
for (int i = 0; i < batchSize; i++) {
currentSequence++;
// 生成3位顺序码
String formattedSequence = String.format(SEQUENCE_TYPE_AF, currentSequence);
sequenceList.add(rulePrefix + formattedSequence);
// 更新顺序码
log.info("===================>更新《{}》顺序码:{}<===================", sequenceKey, formattedSequence);
setValueWithDailyExpiration(sequenceKey, String.valueOf(formattedSequence));
}
return sequenceList;
} finally {
redisTemplate.delete(LOCK_KEY_AF);
}
} else {
// 获取锁失败,可以选择重试或采取其他策略
throw new RuntimeException("Failed to acquire lock for sequence generation");
}
}
/**
* 生成顺序码
*
* @param sequenceKey redisKey
* @param sequenceType 生成码类型
* @param lockKey redis锁
* @return s
*/
public String generateSequence(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);
currentSequence++;
// 生成顺序码
String formattedSequence = String.format(sequenceType, currentSequence);
log.info("===================>更新《{}》顺序码:{}<===================", sequenceKey, formattedSequence);
// 更新顺序码
if (lockKey.equals(LOCK_KEY_DR)) {
setValueWithMonthlyExpiration(sequenceKey, String.valueOf(formattedSequence));
} else {
setValueWithYearlyExpiration(sequenceKey, String.valueOf(formattedSequence));
}
String generatedSequence = sequenceKey + formattedSequence;
String result = generatedSequence + (lockKey.equals(LOCK_KEY_DR) ? "" : rulePrefix);
log.info("===================>返回《{}》顺序码:{}<===================", sequenceKey, result);
return result;
} finally {
releaseLock(lockKey);
}
} else {
throw new RuntimeException("Failed to acquire lock for sequence generation");
}
}
/**
* 生成顺序码
*
* @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
* @return bool
*/
private Boolean obtainLock(String lockKey) {
return redisTemplate.opsForValue().setIfAbsent(lockKey, LOCK_VALUE);
}
/**
* 释放锁
*
* @param lockKey lockKey
*/
private void releaseLock(String lockKey) {
redisTemplate.delete(lockKey);
}
/**
* redis 根据自然日过期
*
* @param key key
* @param value value
*/
public void setValueWithDailyExpiration(String key, String value) {
Date endOfDay = DateUtils.calculateEndOfDay(new Date());
setValueWithExpiration(key, value, endOfDay);
}
/**
* redis 根据自然月过期
*
* @param key key
* @param value value
*/
public void setValueWithMonthlyExpiration(String key, String value) {
Date endOfMonth = DateUtils.calculateEndOfMonth(new Date());
setValueWithExpiration(key, value, endOfMonth);
}
/**
* redis 根据自然年过期
*
* @param key key
* @param value value
*/
public void setValueWithYearlyExpiration(String key, String value) {
Date endOfYear = DateUtils.calculateEndOfYear(new Date());
setValueWithExpiration(key, value, endOfYear);
}
/**
* redis设置key
*
* @param key key
* @param value value
* @param expirationDate 过期时间
*/
public void setValueWithExpiration(String key, String value, Date expirationDate) {
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
valueOps.set(key, value);
long expirationTimeInSeconds = expirationDate.getTime() - System.currentTimeMillis();
redisTemplate.expire(key, expirationTimeInSeconds, TimeUnit.MILLISECONDS);
}
}
\ No newline at end of file
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