优化模具管理,增加模具重复校验

This commit is contained in:
杨晓东 2025-12-01 16:59:55 +08:00
parent 8acd666cd3
commit 59db4b9aec

View File

@ -58,7 +58,10 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService
{
LambdaQueryWrapper<DryParamThreshold> queryWrapper = new LambdaQueryWrapper<>(dryParamThreshold);
return dryParamThresholdMapper.selectList(queryWrapper.orderByDesc(DryParamThreshold::getRuleCode));
return dryParamThresholdMapper.selectList(queryWrapper
.orderByDesc(DryParamThreshold::getIsEnabled)
.orderByDesc(DryParamThreshold::getCreateTime)
.orderByDesc(DryParamThreshold::getUpdateTime));
}
/**
@ -70,13 +73,31 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService
@Override
public int insertDryParamThreshold(DryParamThreshold dryParamThreshold)
{
// 校验 ruleName 是否已存在于数据库
String ruleName = dryParamThreshold.getRuleName().trim();
LambdaQueryWrapper<DryParamThreshold> ruleNameQuery = new LambdaQueryWrapper<DryParamThreshold>()
.eq(DryParamThreshold::getRuleName, ruleName);
long ruleNameCount = dryParamThresholdMapper.selectCount(ruleNameQuery);
if (ruleNameCount > 0) {
throw new RuntimeException(String.format("规则名称【%s】已存在请更换名称后重试", ruleName));
}
// 校验 materialName 是否已存在于数据库
String materialName = dryParamThreshold.getMaterialName().trim();
LambdaQueryWrapper<DryParamThreshold> materialNameQuery = new LambdaQueryWrapper<DryParamThreshold>()
.eq(DryParamThreshold::getMaterialName, materialName);
long materialNameCount = dryParamThresholdMapper.selectCount(materialNameQuery);
if (materialNameCount > 0) {
throw new RuntimeException(String.format("物料名称【%s】已存在请更换名称后重试", materialName));
}
// 接入MES后使用
// dryParamThreshold.setWorkOrderCode("");
// dryParamThreshold.setProductCode("");
// 自动生成规则代码和物料代码
dryParamThreshold.setRuleCode(generateUniqueCode(dryParamThreshold.getRuleName(), null, dryParamThresholdMapper, code -> new LambdaQueryWrapper<DryParamThreshold>().eq(DryParamThreshold::getRuleCode, code)));
dryParamThreshold.setMaterialCode(generateUniqueCode(null, dryParamThreshold.getMaterialName(), dryParamThresholdMapper, code -> new LambdaQueryWrapper<DryParamThreshold>().eq(DryParamThreshold::getMaterialCode, code)));
dryParamThreshold.setRuleCode(generateUniqueCode(dryParamThreshold.getRuleName(), null, dryParamThresholdMapper));
dryParamThreshold.setMaterialCode(generateUniqueCode(null, dryParamThreshold.getMaterialName(), dryParamThresholdMapper));
dryParamThreshold.setCreateBy(SecurityUtils.getUsername());
dryParamThreshold.setCreateTime(DateUtils.getNowDate());
@ -93,6 +114,23 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService
@Override
public int updateDryParamThreshold(DryParamThreshold dryParamThreshold)
{
String ruleName = dryParamThreshold.getRuleName().trim();
LambdaQueryWrapper<DryParamThreshold> ruleNameQuery = new LambdaQueryWrapper<DryParamThreshold>()
.eq(DryParamThreshold::getRuleName, ruleName);
long ruleNameCount = dryParamThresholdMapper.selectCount(ruleNameQuery);
if (ruleNameCount > 0) {
throw new RuntimeException(String.format("规则名称【%s】已存在请更换名称后重试", ruleName));
}
// 校验 materialName 是否已存在于数据库
String materialName = dryParamThreshold.getMaterialName().trim();
LambdaQueryWrapper<DryParamThreshold> materialNameQuery = new LambdaQueryWrapper<DryParamThreshold>()
.eq(DryParamThreshold::getMaterialName, materialName);
long materialNameCount = dryParamThresholdMapper.selectCount(materialNameQuery);
if (materialNameCount > 0) {
throw new RuntimeException(String.format("物料名称【%s】已存在请更换名称后重试", materialName));
}
dryParamThreshold.setUpdateBy(SecurityUtils.getUsername());
dryParamThreshold.setUpdateTime(DateUtils.getNowDate());
@ -126,140 +164,119 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService
}
/**
* 根据名称和类型生成唯一 ruleCode / materialCode自动查重重复提示
* @param ruleName 规则名称 rulename 对应 "用户注册规则"materialname 对应 "不锈钢板材"
* 生成唯一 ruleCode / materialCode
* @param ruleName 规则名称
* @param materialName 物料名称
* @param dryParamThresholdMapper
* @return 唯一编码
* @param mapper DryParamThresholdMapper 实例
* @return 纯英文唯一编码
* @throws RuntimeException 输入非法或编码重复
*/
public static String generateUniqueCode(String ruleName, String materialName,
com.baomidou.mybatisplus.core.mapper.BaseMapper dryParamThresholdMapper,
java.util.function.Function<String, LambdaQueryWrapper> queryWrapperFunc) {
com.baomidou.mybatisplus.core.mapper.BaseMapper<DryParamThreshold> mapper) {
// 1. 确定编码类型名称前缀
String name;
String prefix;
if (ruleName == null) {
name = materialName;
prefix = "MATERIAL_";
} else {
name = ruleName;
boolean isRuleCode;
if (ruleName != null && !ruleName.trim().isEmpty()) {
name = ruleName.trim();
prefix = "RULE_";
isRuleCode = true;
} else if (materialName != null && !materialName.trim().isEmpty()) {
name = materialName.trim();
prefix = "MATERIAL_";
isRuleCode = false;
} else {
throw new RuntimeException("输入名称不能为空ruleName 和 materialName 不能同时为空)");
}
// 1. 输入校验
if (name == null || name.trim().isEmpty()) {
throw new RuntimeException("输入名称不能为空");
// 2. 名称预处理清理特殊字符 + 中文转纯英文拼音核心避免中文编码
String cleanName = Pattern.compile("[^a-zA-Z0-9\u4e00-\u9fa5]").matcher(name).replaceAll("");
String englishName = chineseToPinyin(cleanName);
if (englishName.isEmpty()) {
englishName = "DEF"; // 兜底避免空拼音导致编码异常
}
// 清理名称中的特殊字符保留中文字母数字
String cleanName = Pattern.compile("[^a-zA-Z0-9\u4e00-\u9fa5]").matcher(name.trim()).replaceAll("");
String englishName = chineseToFullPinyin(cleanName); // 中文转英文拼音
int maxRetry = 3; // 最多重试3次避免死循环
// 2. 生成编码 + 查重
int maxRetry = 5; // 重试次数5次降低重复概率
for (int i = 0; i < maxRetry; i++) {
String candidateCode;
// 规则1ruleName RULE_名称前4字大写_8位随机码
if (ruleName != null) {
// 3. 生成编码按原规则强化纯英文
if (isRuleCode) {
// ruleCode前缀_拼音前4位大写_6位随机码
String nameAbbr = englishName.length() > 4 ? englishName.substring(0, 4) : englishName;
nameAbbr = nameAbbr.toUpperCase(); // 转大写
String randomSuffix = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
nameAbbr = nameAbbr.toUpperCase();
String randomSuffix = UUID.randomUUID().toString().replace("-", "").substring(0, 6).toUpperCase();
candidateCode = String.format("%s%s_%s", prefix, nameAbbr, randomSuffix);
}
// 规则2materialName MATERIAL_名称首字母大写_8位随机码
else {
} else {
// materialCode前缀_拼音首字母大写_6位随机码
StringBuilder initials = new StringBuilder();
boolean isFirstChar = true;
for (char c : englishName.toCharArray()) {
// 仅取英文单词的首字母拼音已无中文直接判断字母
if (isFirstChar && Character.isLetter(c)) {
initials.append(Character.toUpperCase(c));
isFirstChar = false;
} else if (Character.isWhitespace(c)) {
isFirstChar = true; // 空格分隔后重新识别首字母
isFirstChar = true;
}
}
String initStr = initials.length() > 0 ? initials.toString() : "DEF";
String randomSuffix = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
String randomSuffix = UUID.randomUUID().toString().replace("-", "").substring(0, 6).toUpperCase();
candidateCode = String.format("%s%s_%s", prefix, initStr, randomSuffix);
}
// 查重
long count;
LambdaQueryWrapper queryWrapper = queryWrapperFunc.apply(candidateCode);
count = dryParamThresholdMapper.selectCount(queryWrapper);
// 4. 同字段查重核心确保当前字段内无重复
LambdaQueryWrapper<DryParamThreshold> queryWrapper = new LambdaQueryWrapper<>();
if (isRuleCode) {
queryWrapper.eq(DryParamThreshold::getRuleCode, candidateCode);
} else {
queryWrapper.eq(DryParamThreshold::getMaterialCode, candidateCode);
}
// 无重复则返回编码
long count = mapper.selectCount(queryWrapper);
if (count == 0) {
return candidateCode;
return candidateCode; // 无重复则返回
}
}
// 重试3次仍重复抛出明确提示
throw new RuntimeException("生成失败:编码重复,请更换名称或稍后重试");
// 重试5次仍重复抛出明确异常
String codeType = isRuleCode ? "ruleCode" : "materialCode";
throw new RuntimeException(String.format("生成%s失败编码重复已重试5次请更换名称或稍后重试", codeType));
}
/**
* 核心辅助方法基于 pinyin4j 将中文转为完整拼音无音调纯英文
* 支持中文全拼英文直接保留数字忽略不影响编码格式
*/
private static String chineseToFullPinyin(String input) {
if (input == null || input.isEmpty()) {
private static String chineseToPinyin(String chinese) {
if (chinese == null || chinese.isEmpty()) {
return "";
}
// 配置拼音输出格式无音调zhang而非zhang1
// 配置拼音格式无音调gan而非gan1
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
StringBuilder pinyin = new StringBuilder();
for (char c : input.toCharArray()) {
// 英文直接保留
if (Character.isLetter(c)) {
pinyin.append(c);
continue;
}
// 数字忽略编码中已有随机码数字无需参与拼音生成
if (Character.isDigit(c)) {
continue;
}
// 中文转全拼pinyin4j 支持所有常用中文
try {
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyinArray != null && pinyinArray.length > 0) {
pinyin.append(pinyinArray[0]); // 取第一个拼音多音字默认取第一个可根据需求扩展
} else {
pinyin.append("unknown"); // 极少数生僻字默认值可调整
for (char c : chinese.toCharArray()) {
// 中文汉字转拼音
if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
try {
// 获取该汉字的所有拼音多音字取第一个
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyinArray != null && pinyinArray.length > 0) {
pinyin.append(pinyinArray[0]); // 取第一个拼音xing
} else {
pinyin.append("unknown"); // 生僻字兜底
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
pinyin.append("unknown"); // 异常兜底
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
pinyin.append("unknown"); // 异常情况兜底
} else if (Character.isLetterOrDigit(c)) {
// 字母/数字直接保留
pinyin.append(c);
} else {
// 特殊字符替换为下划线后续会被清理不影响编码
pinyin.append("_");
}
}
// 去除连续重复字符AAA避免拼音过长
return removeContinuousDuplicates(pinyin.toString()).trim();
}
/**
* 辅助方法3去除拼音中的连续重复字符yongoongyongong优化编码长度
*/
private static String removeContinuousDuplicates(String str) {
if (str == null || str.length() <= 1) {
return str;
}
StringBuilder sb = new StringBuilder();
sb.append(str.charAt(0));
for (int i = 1; i < str.length(); i++) {
char current = str.charAt(i);
char last = sb.charAt(sb.length() - 1);
if (current != last) {
sb.append(current);
}
}
return sb.toString();
return pinyin.toString();
}
}