编码设置的原因
-
通过这个自动生成编码的程序,我们可以快速精确地为每个生产批次,产品或组件生成唯一的标识
-
它能够帮助我们解决在生产过程中需要记录和报告详细信息的问题,
-
自动生成编码确保了数据的准确性,为生产计划、设备维护、人力资源规划等方面提供了可靠的信息
-
可以减少人工输入的时间和可能出现输入错误的情况,从而提高整体的生产效率。
自动编码生成
-
在我们的数据库中是有三张表的,它们分别为:编码生成规则表,编码生成规则组成表,编码生成记录表;
-
CREATE TABLE `mes_code_rule` ( `rule_id` bigint NOT NULL AUTO_INCREMENT COMMENT '规则ID', `rule_code` varchar(64) NOT NULL COMMENT '规则编码', `rule_name` varchar(255) NOT NULL COMMENT '规则名称', `rule_desc` varchar(500) DEFAULT NULL COMMENT '描述', `max_length` int DEFAULT NULL COMMENT '最大长度', `is_padded` char(1) NOT NULL COMMENT '是否补齐', `padded_char` varchar(20) DEFAULT NULL COMMENT '补齐字符', `padded_method` char(1) DEFAULT 'L' COMMENT '补齐方式', `enable_flag` char(1) NOT NULL DEFAULT 'Y' COMMENT '是否启用', `remark` varchar(500) DEFAULT '' COMMENT '备注', `attr1` varchar(64) DEFAULT NULL COMMENT '预留字段1', `attr2` varchar(255) DEFAULT NULL COMMENT '预留字段2', `attr3` int DEFAULT '0' COMMENT '预留字段3', `attr4` int DEFAULT '0' COMMENT '预留字段4', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`rule_id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `mes_code_part` ( `part_id` bigint NOT NULL AUTO_INCREMENT COMMENT '分段ID', `rule_id` bigint NOT NULL COMMENT '规则ID', `part_index` int NOT NULL COMMENT '分段序号', `part_type` varchar(20) NOT NULL COMMENT '分段类型,INPUTCHAR:输入字符,NOWDATE:当前日期时间,FIXCHAR:固定字符,SERIALNO:流水号', `part_code` varchar(64) DEFAULT NULL COMMENT '分段编号', `part_name` varchar(255) DEFAULT NULL COMMENT '分段名称', `part_length` int NOT NULL COMMENT '分段长度', `date_format` varchar(20) DEFAULT NULL COMMENT '日期时间格式', `input_character` varchar(64) DEFAULT NULL COMMENT '输入字符', `fix_character` varchar(64) DEFAULT NULL COMMENT '固定字符', `seria_start_no` int DEFAULT NULL COMMENT '流水号起始值', `seria_step` int DEFAULT NULL COMMENT '流水号步长', `seria_now_no` int DEFAULT NULL COMMENT '流水号当前值', `cycle_flag` char(1) DEFAULT NULL COMMENT '流水号是否循环', `cycle_method` varchar(20) DEFAULT NULL COMMENT '循环方式,YEAR:按年,MONTH:按月,DAY:按天,HOUR:按小时,MINITE:按分钟,OTHER:按传入字符变', `remark` varchar(500) DEFAULT '' COMMENT '备注', `attr1` varchar(64) DEFAULT NULL COMMENT '预留字段1', `attr2` varchar(255) DEFAULT NULL COMMENT '预留字段2', `attr3` int DEFAULT '0' COMMENT '预留字段3', `attr4` int DEFAULT '0' COMMENT '预留字段4', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`part_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `mes_code_result` ( `code_id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID', `rule_id` bigint NOT NULL COMMENT '规则ID', `gen_date` varchar(64) NOT NULL COMMENT '生成日期时间', `gen_index` int DEFAULT NULL COMMENT '最后产生的序号', `last_result` varchar(64) DEFAULT NULL COMMENT '最后产生的值', `last_serial_no` int DEFAULT NULL COMMENT '最后产生的流水号', `last_input_char` varchar(64) DEFAULT NULL COMMENT '最后传入的参数', `remark` varchar(500) DEFAULT '' COMMENT '备注', `attr1` varchar(64) DEFAULT NULL COMMENT '预留字段1', `attr2` varchar(255) DEFAULT NULL COMMENT '预留字段2', `attr3` int DEFAULT '0' COMMENT '预留字段3', `attr4` int DEFAULT '0' COMMENT '预留字段4', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`code_id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4;
-
这个编码生成规则表就是我们对每一个产品编码生成时的总称,如果没有该条数据,就无法生成编码,它里面包含了多个字段,其中比较重要的是:编码的最大的长度,是否补齐字符,补齐字符,补齐字符的方式等;
-
这个编码生成规则组成表才是我们真正需要生成编码时所需要的规范,它跟这个规则表属于是一对多的关系(组成表是多),我们主要是根据三种类型进行开发的,分别为流水号,固定字符,当前日期;其中流水号是最为复杂的,其它两个都是根据相对应的类型返回所对应的值,而流水号的话他需要更加严格的规则封装,例如:规则中包含了流水号的起始值,流水号的步长,是否循环流水号,以哪种方式进行循环(有年,月,日,时,分)等
-
最后的这个编码生成记录表,主要是记录上一次流水号的值,流水号的步长和上一次自动生成编码的结果,当我们的流水号循环时需要从这个表中取值,并最终通过取得的这个值进行生成新的流水号。
后端代码实现
策略设计模式
我们在自动编码生成的过程中使用到了策略设计模式,它里面包含了自定义的公共的策略接口,各种算法类,工厂这些算法类都需要统一实现这个策略接口,还结合了自定义注解,方便让程序知道我们需要哪个算法类,这些算法类都需要办理不同的业务,例如:流水号,当前日期,固定字符都会对应一个算法类, 工厂通常用于创建具体算法类的实例。工厂模式可以进一步帮助将客户端代码与具体的策略实现解耦,因为客户端不需要直接实例化策略类,而是通过工厂来请求所需的策略对象。
1. 首先我们先写一个接口StrageI
public interface StrageI {
public String code(String codeName);
}
2. 并且设置一个自定义注解StrageAn
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//RUNTIME:可以通过反射来获取这个自定义注解的所有内容
@Retention(RetentionPolicy.RUNTIME)
public @interface StrageAn {
public String an();
}
3. 定义一个固定字符FirstChar类并实现我们定义的接口StrageI
/**
* 固定字符
*/
@Component
//使用自定义注解设置唯一标识
@StrageAn(an = "FIXCHAR")
public class FirstChar implements StrageI {
@Override
public String code(String codeName) {
//按照固定字符的设置生成字符串 如:WH
return codeName;
}
}
4. 定义一个当前日期NowDate类并实现我们定义的接口StrageI
import org.springframework.stereotype.Component;
@Component
@StrageAn(an = "NOWDATE")
public class NowDate implements StrageI{
@Override
public String code(String codeName) {
//根据日期模板[yyyyMMdd]结合jdk8新特性 生成日期
return codeName;
}
}
5. 定义一个流水号Number类并实现我们定义的接口StrageI
import org.springframework.stereotype.Component;
@Component
@StrageAn(an = "SERIALNO")
public class Number implements StrageI {
@Override
public String code(String codeName) {
//根据当前起始值和步长以及其他字段生成指定长度的流水号 如:0001
return codeName;
}
}
6. 最后定义一个工厂StrageFactory,并加载到我们的容器中
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class StrageFactory implements ApplicationRunner {
//先获取所有的算法类
@Autowired
private List<StrageI> strageIS;
public static Map<String,StrageI> map = new HashMap<>();
//项目启动的时候优先加载run方法中的内容
@Override
public void run(ApplicationArguments args) throws Exception {
for (StrageI strageI : strageIS) {
//反射
Class<? extends StrageI> aClass = strageI.getClass();
//通过反射获取注解
String an = aClass.getAnnotation(StrageAn.class).an();
//放到map集合中
map.put(an, strageI);
}
System.out.println("");
}
}
如果我们的编码组成中选择的是固定字符或者当前日期,我们就可以直接返回固定字符,当前日期我们需要根据用户输入的日期格式进行生成日期并且返回;
流水号:
在刚开始的时候我们先需要查询编码生成记录表中是否有这个最后产生流水号的值,如果有的话我们需要根据这个值进行增长,如果没有的话才会根据这个流水号的起始值进行增长,之后我们需要查看一下该规则是否需要循环,如果不需要的话,按正常的流程继续操作即可,如果需要循环的话,那么就需要查看一下他需要的循环方式,并且根据相对应的循环方式设定时间,如果到时间了,就需要重新以流水号的起始值再次与对应的步长进行增长;最后如果流水号的长度没有达到设定的长度,就需要补齐字符串,补齐的字符串为"0";默认是左补齐(一般不建议更改)。
如果没有设置编码规则的话,就会返回错误信息提示用户创建规则。
话不多说,直接上代码,毕竟代码才是最好的交流方式。
具体实现自动编码代码:
1. 跟前端交互result
public enum Constant {
SUCCESS_MSG(1, "操作成功"),
FAIL_MSG(2, "操作失败");
private Integer code;
private String message;
private Object data;
Constant() {
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
Constant(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
Constant(Integer code, String message) {
this.code = code;
this.message = message;
}
/**
* 获取
* @return code
*/
public Integer getCode() {
return code;
}
/**
* 设置
* @param code
*/
public void setCode(Integer code) {
this.code = code;
}
/**
* 获取
* @return message
*/
public String getMessage() {
return message;
}
/**
* 设置
* @param message
*/
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "Constant{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
private Integer code;
private String message;
private Object data;
public Result(Constant constant) {
this.code = constant.getCode();
this.message = constant.getMessage();
}
//成功统一返回结果
public static Result OK() {
Result Result = new Result(Constant.SUCCESS);
return Result;
}
//统一返回结果
public static Result response(Constant constant,Object data) {
Result Result = new Result();
Result.setCode(constant.getCode());
Result.setMessage(constant.getMessage());
Result.setData(data);
return Result;
}
}
2. 表的反向生成工具generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--加载maven中mysql连接的jar包-->
<classPathEntry location="D:\java8\apache-maven-3.5.4\repo\mysql\mysql-connector-java\8.0.30\mysql-connector-java-8.0.30.jar"></classPathEntry>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true"></property>
</commentGenerator>
<!-- 设定数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/bepot"
userId="root"
password="123456">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成 bean 存放的位置 model -->
<javaModelGenerator targetPackage="com.mes.model" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成的mapper文件的位置 -->
<sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources\">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成的mapper.xml 对应的那个mapper接口的存放位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.mes.mapper" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 设定反向生成的表 -->
<table tableName="mes_code_result"></table>
<!-- <table tableName="mes_code_rule"></table>-->
<!-- <table tableName="mes_warehouse_location"></table>-->
</context>
</generatorConfiguration>
<!--mybatis逆向工程插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
3. 更改后的FixChar
@Component
@StrageAn(an = "FIXCHAR")
public class FixChar implements StrageI {
@Override
public String getCode(MesCodePart mesCodePart) {
String fixCharacter = mesCodePart.getFixCharacter();
//按照固定字符的设置生成字符串
return fixCharacter;
}
}
4. 更改后的NowDate
@Component
@StrageAn(an = "NOWDATE")
public class NowDate implements StrageI {
@Override
public String getCode(MesCodePart mesCodePart) {
//根据日期模板[yyyyMMdd]结合jdk8新特性 生成日期
//把日期时间格式传入
String format = new SimpleDateFormat(mesCodePart.getDateFormat()).format(new Date());
return format;
}
}
5. 更改后的Number
@Component
@StrageAn(an = "SERIALNO")
public class Number implements StrageI {
@Autowired
private MesCodeResultMapper resultMapper;
private Integer seriaStartNo;
@Override
public String getCode(MesCodePart mesCodePart) throws Exception {
//根据当前起始值和步长以及其他字段生成指定长度的流水号0001
MesCodeResultExample example = new MesCodeResultExample();
MesCodeResultExample.Criteria criteria = example.createCriteria();
criteria.andRuleIdEqualTo(mesCodePart.getRuleId());
//根据传来的外键规则id查询所有记录
List<MesCodeResult> resultList = resultMapper.selectByExample(example);
//定义一个当前参数值
int current = 0;
Integer seriaStep = mesCodePart.getSeriaStep(); //步长
int partLength = mesCodePart.getPartLength();//分段长度
//如果记录流水号表(集合)为空的情况下
if(resultList.size() == 0){
//给seriaStartNo 赋值为初始值
seriaStartNo = mesCodePart.getSeriaStartNo();
current = seriaStartNo;//初始值给当前值
}else {
//获取记录表中最后产生的流水号
seriaStartNo = resultList.get(0).getLastSerialNo();
current = seriaStartNo;//初始值给当前值
current += seriaStep; // 递增流水号
}
//记录实体类
MesCodeResult mesCodeResult = new MesCodeResult();
//如果记录流水号表集合不为空的情况下
if(resultList.size() != 0){
//获取记录表主键
Long codeId = resultList.get(0).getCodeId();
//获取当前时间转成字符串的形式
String s = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
//给对象赋值
mesCodeResult.setCodeId(codeId);
mesCodeResult.setGenDate(s);
//String.format("%0"+partLength+"d", current) 表示把传来的流水号和分段长度进行补0操作
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", current));
//LastSerialNo 记录最后的流水号
mesCodeResult.setLastSerialNo(current);
mesCodeResult.setUpdateTime(new Date());
//判断是否循环
if (mesCodePart.getCycleFlag().equals("Y")){
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss 'CST' yyyy",Locale.ENGLISH);
//把备用时间转成date格式
Date parse = sdf.parse(resultList.get(0).getAttr1());
//获取备用时间的毫秒值
long time = parse.getTime();
Date date = new Date();
//获取当前时间的毫秒值
long dateTime = date.getTime();
//用于存循环后的流水号
int seria = 0;
//判断是否按年循环
if (mesCodePart.getCycleMethod().equals("YEAR")){
//判断备用时间的毫秒值加上一年的毫秒值是否小于当前时间的毫秒值
if (time + 365*24*60*60*1000 < dateTime){ //true
//获取分段表初始值给seria赋值
seria = mesCodePart.getSeriaStartNo();
//给对象赋值
mesCodeResult.setLastSerialNo(seria);
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", seria));
//修改备用时间为当前值
mesCodeResult.setAttr1(date.toString());
}
}else if (mesCodePart.getCycleMethod().equals("MONTH")){ //判断是否按月循环
//判断备用时间的毫秒值加上月的毫秒值是否小于当前时间的毫秒值
if (time + 30*24*60*60*1000 < dateTime){
//获取分段表初始值给seria赋值
seria = mesCodePart.getSeriaStartNo();
mesCodeResult.setLastSerialNo(seria);
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", seria));
//修改备用时间为当前值
mesCodeResult.setAttr1(date.toString());
}
}else if (mesCodePart.getCycleMethod().equals("DAY")){ //判断是否按天循环
//判断备用时间的毫秒值加上天的毫秒值是否小于当前时间的毫秒值
if (time + 24*60*60*1000 < dateTime){
//获取分段表初始值给seria赋值
seria = mesCodePart.getSeriaStartNo();
mesCodeResult.setLastSerialNo(seria);
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", seria));
//修改备用时间为当前值
mesCodeResult.setAttr1(date.toString());
}
}else if (mesCodePart.getCycleMethod().equals("HOUR")){ //判断是否按小时循环
//判断备用时间的毫秒值加小时的毫秒值是否小于当前时间的毫秒值
if (time + 60*60*1000 < dateTime){
//获取分段表初始值给seria赋值
seria = mesCodePart.getSeriaStartNo();
mesCodeResult.setLastSerialNo(seria);
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", seria));
//修改备用时间为当前值
mesCodeResult.setAttr1(date.toString());
}
}else if (mesCodePart.getCycleMethod().equals("MINUTE")){ //判断是否按分钟循环
//判断备用时间的毫秒值加分钟的毫秒值是否小于当前时间的毫秒值
if (time + 60*1000 < dateTime){
//获取分段表初始值给seria赋值
seria = mesCodePart.getSeriaStartNo();
mesCodeResult.setLastSerialNo(seria);
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", seria));
//修改备用时间为当前值
mesCodeResult.setAttr1(date.toString());
}
}
}
//给分段对象做修改操作
resultMapper.updateByPrimaryKeySelective(mesCodeResult);
}else { //如果记录流水号表集合为空的情况下
//获取分段表的主键给记录表的外键赋值
mesCodeResult.setRuleId(mesCodePart.getRuleId());
//获取当前时间转成字符串的形式
String s = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
mesCodeResult.setGenDate(s);
//传来的流水号和分段长度进行补0操作
mesCodeResult.setLastResult(String.format("%0"+partLength+"d", current));
mesCodeResult.setLastSerialNo(current);
mesCodeResult.setCreateTime(new Date());
mesCodeResult.setAttr1(new Date().toString());
//添加操作
resultMapper.insertSelective(mesCodeResult);
}
//获取到记录表中最后产生的值
String format1 = mesCodeResult.getLastResult();
return format1;
}
}
6. CodeController层
@RestController
@RequestMapping("/code")
public class CodeController {
@Autowired
private CodeService codeService;
@GetMapping("/findByName")
public Result getCode(String codeName){
try {
Result result = codeService.findByName(codeName);
return new Result(result.getCode(),result.getMessage(),result.getData());
} catch (Exception e) {
return new Result(-1,e.getMessage(),null);
}
}
}
7. CodeService接口层
public interface CodeService {
Result findByName(String codeName);
}
8. CodeServiceImpl实现层
@Service
public class CodeServiceImpl implements CodeService {
@Autowired
private MesCodeRuleMapper ruleMapper;
@Autowired
private MesCodePartMapper partMapper;
@Autowired
private MesCodeResultMapper resultMapper;
@Override
public Result findByName(String codeName) {
try {
MesCodeRuleExample example = new MesCodeRuleExample();
MesCodeRuleExample.Criteria criteria = example.createCriteria();
criteria.andRuleCodeEqualTo(codeName);
List<MesCodeRule> ruleList = ruleMapper.selectByExample(example);
if (ruleList.size() > 0) {
MesCodeRule mesCodeRule = ruleList.get(0);
MesCodePartExample mesCodePartExample = new MesCodePartExample();
MesCodePartExample.Criteria criteria1 = mesCodePartExample.createCriteria().andRuleIdEqualTo(mesCodeRule.getRuleId());
List<MesCodePart> partList = partMapper.selectByExample(mesCodePartExample);
//判断分段表集合为空
if (partList.size() == 0){
return new Result(-1,"规则组成["+codeName+"]不能为空",null);
}
//分段表不为空
//定义一个集合,sortTing用于储存分段序号和策略工厂传来的值
List<sortTing> list = new ArrayList<>();
//遍历分段表集合,获取每一个对象
for (MesCodePart part : partList) {
Map<String, StrageI> map = StrageFactory.map;
//获取到分段表的类型值
StrageI strageI = map.get(part.getPartType());
//调用类型实现类的方法,获取到操作完的字符
String code = strageI.getCode(part);
//存入集合
list.add(new sortTing(part.getPartIndex(),code));
}
//给集合进行序号排序
Collections.sort(list,(a,d) ->{
return a.getPartIndex() - d.getPartIndex();
});
//定义一个StringBuilder集合
StringBuilder sb = new StringBuilder();
//判断是否补齐 Y是 N否
if (ruleList.get(0).getIsPadded().equals("Y")){
//获取到规则长度
Integer maxLength = ruleList.get(0).getMaxLength();
//遍历 List<sortTing>集合获取到sortTing对象
for (sortTing sortTing : list){
//把操作完的字符串进行拼接,存入StringBuilder
sb.append(sortTing.getCode());
}
//获取到剩余的长度
int i = maxLength - sb.length();
//如果规则剩余长度大于0
if (i > 0){
//循环i
for (int j = 0; j < i; j++) {
//判断是不是左补齐
if (ruleList.get(0).getPaddedMethod().equals("L")){
//从下标0插入需要补齐的字符
sb.insert(0,ruleList.get(0).getPaddedChar());
} else {//右补齐
//直接在StringBuilder后拼接需要补齐的字符
sb.append(ruleList.get(0).getPaddedChar());
}
}
}
}else { //不补齐
for (sortTing sortTing : list){
//把操作完的字符串进行拼接,存入StringBuilder
sb.append(sortTing.getCode());
}
}
//遍历分段表集合,获取每一个对象
for (MesCodePart part : partList){
//记录实体类
MesCodeResultExample resultExample = new MesCodeResultExample();
MesCodeResult mesCodeResult = new MesCodeResult();
MesCodeResultExample.Criteria criteria2 = resultExample.createCriteria();
//获取记录表外键
criteria2.andRuleIdEqualTo(part.getRuleId());
//根据外键查询出集合
List<MesCodeResult> resultList = resultMapper.selectByExample(resultExample);
if (resultList.size() != 0){
//根据外键查询出集合,获取到记录表的主键
mesCodeResult.setCodeId(resultList.get(0).getCodeId());
//把拼接好的最后的流水号存入记录表中
mesCodeResult.setLastResult(sb.toString());
//进行记录表的修改操作
resultMapper.updateByPrimaryKeySelective(mesCodeResult);
}
}
return Result.response(Constant.SUCCESS_MSG,sb.toString());
} else {
return new Result(-1,"请录入["+codeName+"]编码规则",null);
}
} catch (Exception e) {
return Result.response(Constant.FAIL_MSG,null);
}
}
}
实现效果:
结论:
自动编码功能,能够通过自动化生成唯一标识,提高了生产效率,减少了人为错误,增强了产品追溯能力,优化了库存管理,并提升了企业的整体运营效率和数据准确性。