数据编码服务中新增序列号生成逻辑

新增序列号生成服务,支持三种不同的编码规则:
1. 日期+递增数字(年月日或年月)。
2. 随机生成的8位序列号,包含大写字母和数字。
3. 默认规则,自增序列号。

实现具有不同前缀和后缀的序列号生成,包括年月日或年月作为前缀,校验位作为后缀。
This commit is contained in:
lijiaqi 2024-09-11 16:34:35 +08:00
parent 778ea6a1f1
commit 6409d8a578
2 changed files with 212 additions and 5 deletions

View File

@ -47,10 +47,10 @@ public class Code extends BaseEntity {
private String snCode; private String snCode;
@Schema(description = "无人机序列号前缀") @Schema(description = "无人机序列号前缀")
private String snPrefix; private Long snPrefix;
@Schema(description = "无人机序列号后缀") @Schema(description = "无人机序列号后缀")
private String snSuffix; private Long snSuffix;
@Schema(description = "无人机序列号长度") @Schema(description = "无人机序列号长度")
private String snLength; private String snLength;

View File

@ -1,11 +1,16 @@
package cn.workde.module.drone.coding.service; package cn.workde.module.drone.coding.service;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.workde.core.base.BaseService; import cn.workde.core.base.BaseService;
import com.baomidou.mybatisplus.extension.service.IService; import cn.workde.core.exception.ResultException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.workde.module.drone.coding.mapper.CodeMapper;
import cn.workde.module.drone.coding.entity.Code; import cn.workde.module.drone.coding.entity.Code;
import cn.workde.module.drone.coding.mapper.CodeMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.security.SecureRandom;
/** /**
* 无人机编码表(Code)表服务实现类 * 无人机编码表(Code)表服务实现类
@ -15,6 +20,208 @@ import org.springframework.stereotype.Service;
*/ */
@Service("codeService") @Service("codeService")
public class CodeService extends BaseService<CodeMapper, Code>{ public class CodeService extends BaseService<CodeMapper, Code>{
private static final String UPPER_CASE_LETTERS = "ABCDEFGHJKLMNPQRSTUVWXYZ";
private static final String NUMBERS = "0123456789";
private static final String VALID_CHARS = UPPER_CASE_LETTERS + NUMBERS;
private static final SecureRandom random = new SecureRandom();
public static String generateSNCode(int totalLength, int upperCaseCount, int numberCount) {
if (totalLength < upperCaseCount + numberCount) {
throw new IllegalArgumentException("Total length must be greater than or equal to the sum of upperCaseCount and numberCount.");
}
StringBuilder snCode = new StringBuilder();
// 添加指定数量的大写字母
for (int i = 0; i < upperCaseCount; i++) {
snCode.append(UPPER_CASE_LETTERS.charAt(random.nextInt(UPPER_CASE_LETTERS.length())));
}
// 添加指定数量的数字
for (int i = 0; i < numberCount; i++) {
snCode.append(NUMBERS.charAt(random.nextInt(NUMBERS.length())));
}
// 添加剩余的字符可以是大写字母或数字
for (int i = 0; i < totalLength - upperCaseCount - numberCount; i++) {
snCode.append(VALID_CHARS.charAt(random.nextInt(VALID_CHARS.length())));
}
// 打乱整个SN码以增加随机性
for (int i = snCode.length() - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
char a = snCode.charAt(index);
snCode.setCharAt(index, snCode.charAt(i));
snCode.setCharAt(i, a);
}
return snCode.toString();
}
public static void main(String[] args) {
// 示例生成一个总长度为12的SN码包含5个大写字母和3个数字
String snCode = generateSNCode(12, 5, 6);
System.out.println("Generated SN Code: " + snCode);
}
@Transactional(rollbackFor = Exception.class)
public synchronized void generateCode(String batchesId, String batchesCode, String mfcId, String mfcCode, String ruleId, String ruleCode, Integer count) {
switch (ruleCode) {
// 序列号 年月日+6位递增数字
case "001":
generateCode001(batchesId, batchesCode, mfcId, mfcCode, ruleId, ruleCode, count);
break;
// 序列号 年月+6位递增数字
case "002":
generateCode002(batchesId, batchesCode, mfcId, mfcCode, ruleId, ruleCode, count);
break;
// 序列号 8位随机数除大写字母OI的数字(0~9)大写字母(A~Z)及其组合组成
case "003":
generateCode003(batchesId, batchesCode, mfcId, mfcCode, ruleId, ruleCode, count);
break;
default:
throw new ResultException("规则待开发 请联系管理员");
}
}
@Transactional(rollbackFor = Exception.class)
public synchronized void generateCode001(String batchesId, String batchesCode, String mfcId, String mfcCode, String ruleId, String ruleCode, Integer count) {
try {
int i = 0;
do {
// 获取年月日
String date = DateUtil.format(DateUtil.date(), "yyyyMMdd");
//转换成long
long dateLong = Long.parseLong(date);
// 初始值 如果当天为创建序列号的话则最大值设置为1
long maxCode = 1;
// 序列号
String snCode = "";
// 获取数据库最大值
Code one = getOne(new QueryWrapper<Code>()
.lambda()
.select(Code::getSnSuffix)
.eq(Code::getSnPrefix, dateLong)
.orderByDesc(Code::getSnSuffix)
.last("limit 1")
);
if (ObjUtil.isNotNull(one)) {
// one.getSnSuffix()超过6位数
if (one.getSnSuffix() >= 999999) {
throw new ResultException("超过最大值");
}
// 年月日+6位递增数字
snCode = date + String.format("%06d", one.getSnSuffix() + 1);
} else {
// 当天还未创建序列号
snCode = date + String.format("%06d", maxCode);
}
Code code = new Code();
code.setBatchesId(batchesId);
code.setBatchesCode(batchesCode);
code.setMfcId(mfcId);
code.setMfcCode(mfcCode);
code.setRuleId(ruleId);
code.setRuleCode(ruleCode);
code.setSnCode(snCode);
code.setSnPrefix(dateLong);
code.setSnSuffix(one.getSnSuffix() + 1);
code.setSnLength("E");
code.setCode(mfcCode + "E" + snCode);
boolean flag = save(code);
if (!flag) throw new ResultException("生成失败");
i++;
} while (i < count);
} catch (Exception e) {
throw new ResultException(e.getMessage());
}
}
@Transactional(rollbackFor = Exception.class)
public synchronized void generateCode002(String batchesId, String batchesCode, String mfcId, String mfcCode, String ruleId, String ruleCode, Integer count) {
try {
int i = 0;
do {
// 获取年月
String date = DateUtil.format(DateUtil.date(), "yyyyMM");
//转换成long
long dateLong = Long.parseLong(date);
// 初始值 如果当天为创建序列号的话则最大值设置为1
long maxCode = 1;
// 序列号
String snCode = "";
// 获取数据库最大值
Code one = getOne(new QueryWrapper<Code>()
.lambda()
.select(Code::getSnSuffix)
.eq(Code::getSnPrefix, dateLong)
.orderByDesc(Code::getSnSuffix)
.last("limit 1")
);
if (ObjUtil.isNotNull(one)) {
// one.getSnSuffix()超过6位数
if (one.getSnSuffix() >= 999999) {
throw new ResultException("超过最大值");
}
// 年月日+6位递增数字
snCode = date + String.format("%06d", one.getSnSuffix() + 1);
} else {
// 当天还未创建序列号
snCode = date + String.format("%06d", maxCode);
}
Code code = new Code();
code.setBatchesId(batchesId);
code.setBatchesCode(batchesCode);
code.setMfcId(mfcId);
code.setMfcCode(mfcCode);
code.setRuleId(ruleId);
code.setRuleCode(ruleCode);
code.setSnCode(snCode);
code.setSnPrefix(dateLong);
code.setSnSuffix(one.getSnSuffix() + 1);
code.setSnLength("C");
code.setCode(mfcCode + "C" + snCode);
boolean flag = save(code);
if (!flag) throw new ResultException("生成失败");
i++;
} while (i < count);
} catch (Exception e) {
throw new ResultException(e.getMessage());
}
}
@Transactional(rollbackFor = Exception.class)
public synchronized void generateCode003(String batchesId, String batchesCode, String mfcId, String mfcCode, String ruleId, String ruleCode, Integer count) {
try {
int i = 0;
do {
String snCode = generateSNCode(8, 5, 3);
long counted = count(new QueryWrapper<Code>()
.lambda()
.eq(Code::getSnCode, snCode)
);
if (counted > 0) continue;
Code code = new Code();
code.setBatchesId(batchesId);
code.setBatchesCode(batchesCode);
code.setMfcId(mfcId);
code.setMfcCode(mfcCode);
code.setRuleId(ruleId);
code.setRuleCode(ruleCode);
code.setSnCode(snCode);
code.setSnPrefix(null);
code.setSnSuffix(null);
code.setSnLength("8");
code.setCode(mfcCode + "8" + snCode);
boolean flag = save(code);
if (!flag) throw new ResultException("生成失败");
i++;
} while (i < count);
} catch (Exception e) {
throw new ResultException(e.getMessage());
}
}
} }