package com.ruoyi.system.service.impl;
|
|
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisLock;
|
import com.ruoyi.common.enums.SystemDataNoEnum;
|
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.system.domain.SysSerialNumber;
|
import com.ruoyi.system.service.ISysSerialNumberService;
|
import com.ruoyi.system.service.ISystemDataNoService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.redisson.api.RLock;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
|
import java.util.List;
|
import java.util.concurrent.TimeUnit;
|
|
@Slf4j
|
@Service
|
public class SystemDataNoServiceImpl implements ISystemDataNoService {
|
|
@Autowired
|
private RedisLock redisLock;
|
|
@Autowired
|
private RedisCache redisCache;
|
|
/**流水号启用缓存*/
|
@Value("${custom.serialNumber.cache.enabled:false}")
|
private boolean serialNumberCache;
|
|
@Autowired
|
private ISysSerialNumberService serialNumberService;
|
|
|
@Override
|
public String getNoByKey(SystemDataNoEnum systemDataNoEnum) {
|
String baseNo = systemDataNoEnum.getNo();
|
if (StringUtils.isEmpty(baseNo)) {
|
return "";
|
}
|
|
String dayKey = DateUtils.dateYYMM();
|
String fullKey = baseNo + dayKey;
|
RLock lock = redisLock.lock(Constants.SYS_DATASERIALNUMBER_KEYPREFIX + fullKey);
|
|
try {
|
if (!lock.tryLock(60, TimeUnit.SECONDS)) {
|
throw new RuntimeException("获取锁失败");
|
}
|
|
log.info("{}进入", Thread.currentThread().getName());
|
Integer serial = getOrInitSerialNumber(fullKey, baseNo, dayKey);
|
redisCache.setCacheObject(fullKey, serial, 1000, TimeUnit.DAYS);
|
|
return formatSerialNumber(fullKey, serial);
|
} catch (InterruptedException e) {
|
throw new RuntimeException("获取锁异常", e);
|
} finally {
|
unlockIfHeld(lock);
|
}
|
}
|
|
private Integer getOrInitSerialNumber(String fullKey, String baseNo, String dayKey) {
|
Integer serial = serialNumberCache ? redisCache.getCacheObject(fullKey) : null;
|
|
if (serial != null) {
|
return serial + 1;
|
}
|
|
SysSerialNumber serialNumber = new SysSerialNumber();
|
serialNumber.setKeyStr(baseNo);
|
serialNumber.setKeyAuxStr(dayKey);
|
serialNumber.setNo(fullKey);
|
|
List<SysSerialNumber> existingNumbers = serialNumberService.selectSysSerialNumberList(serialNumber);
|
serial = existingNumbers != null && !existingNumbers.isEmpty()
|
? existingNumbers.get(0).getSerialNumber()
|
: 0;
|
|
if (serial == 0) {
|
serialNumber.setSerialNumber(1);
|
serialNumberService.insertSysSerialNumber(serialNumber);
|
return 1;
|
}
|
return serial + 1;
|
}
|
|
private String formatSerialNumber(String prefix, Integer serial) {
|
return prefix + String.format("%04d", serial);
|
}
|
|
private void unlockIfHeld(RLock lock) {
|
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
|
lock.unlock();
|
}
|
}
|
}
|