优化模具管理,增加模具重复校验
This commit is contained in:
parent
8acd666cd3
commit
59db4b9aec
@ -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;
|
||||
|
||||
// 规则1:ruleName → 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);
|
||||
}
|
||||
|
||||
// 规则2:materialName → 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("_");
|
||||
}
|
||||
}
|
||||
|
||||
// 去除连续重复字符(如“AA”→“A”),避免拼音过长
|
||||
return removeContinuousDuplicates(pinyin.toString()).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助方法3:去除拼音中的连续重复字符(如“yongoong”→“yongong”,优化编码长度)
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user