Commit 3d556dfba406a8083ed8175229c6a18f1e9d81e0

Authored by YunaiV
1 parent 1e235a12

✨ feat(mes): 添加 MES 编码规则相关的请求和响应对象

新增多个请求和响应对象,包括编码规则组成、编码生成等功能,支持管理后台的编码规则管理。
Showing 33 changed files with 1731 additions and 0 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/MesMdAutoCodePartController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAutoCodePartRespVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAutoCodePartSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  8 +import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodePartService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import java.util.List;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +
  22 +@Tag(name = "管理后台 - MES 编码规则组成")
  23 +@RestController
  24 +@RequestMapping("/mes/auto-code-part")
  25 +@Validated
  26 +public class MesMdAutoCodePartController {
  27 +
  28 + @Resource
  29 + private MesMdAutoCodePartService partService;
  30 +
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建规则组成")
  33 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:update')")
  34 + public CommonResult<Long> createAutoCodePart(@Valid @RequestBody MesMdAutoCodePartSaveReqVO createReqVO) {
  35 + return success(partService.createAutoCodePart(createReqVO));
  36 + }
  37 +
  38 + @PutMapping("/update")
  39 + @Operation(summary = "更新规则组成")
  40 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:update')")
  41 + public CommonResult<Boolean> updateAutoCodePart(@Valid @RequestBody MesMdAutoCodePartSaveReqVO updateReqVO) {
  42 + partService.updateAutoCodePart(updateReqVO);
  43 + return success(true);
  44 + }
  45 +
  46 + @DeleteMapping("/delete")
  47 + @Operation(summary = "删除规则组成")
  48 + @Parameter(name = "id", description = "编号", required = true)
  49 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:update')")
  50 + public CommonResult<Boolean> deleteAutoCodePart(@RequestParam("id") Long id) {
  51 + partService.deleteAutoCodePart(id);
  52 + return success(true);
  53 + }
  54 +
  55 + @GetMapping("/get")
  56 + @Operation(summary = "获得规则组成")
  57 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  58 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:query')")
  59 + public CommonResult<MesMdAutoCodePartRespVO> getAutoCodePart(@RequestParam("id") Long id) {
  60 + MesMdAutoCodePartDO part = partService.getAutoCodePart(id);
  61 + return success(BeanUtils.toBean(part, MesMdAutoCodePartRespVO.class));
  62 + }
  63 +
  64 + @GetMapping("/list-by-rule-id")
  65 + @Operation(summary = "根据规则 ID 获得规则组成列表")
  66 + @Parameter(name = "ruleId", description = "规则 ID", required = true, example = "1")
  67 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:query')")
  68 + public CommonResult<List<MesMdAutoCodePartRespVO>> getAutoCodePartListByRuleId(@RequestParam("ruleId") Long ruleId) {
  69 + List<MesMdAutoCodePartDO> list = partService.getAutoCodePartListByRuleId(ruleId);
  70 + return success(BeanUtils.toBean(list, MesMdAutoCodePartRespVO.class));
  71 + }
  72 +
  73 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/MesMdAutoCodeRecordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.record.MesMdAutoCodeGenerateReqVO;
  5 +import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
  6 +import io.swagger.v3.oas.annotations.Operation;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import jakarta.annotation.Resource;
  9 +import jakarta.validation.Valid;
  10 +import org.springframework.security.access.prepost.PreAuthorize;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.*;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  15 +
  16 +@Tag(name = "管理后台 - MES 编码生成记录")
  17 +@RestController
  18 +@RequestMapping("/mes/auto-code-record")
  19 +@Validated
  20 +public class MesMdAutoCodeRecordController {
  21 +
  22 + @Resource
  23 + private MesMdAutoCodeRecordService recordService;
  24 +
  25 + @PostMapping("/generate")
  26 + @Operation(summary = "生成编码")
  27 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:query')")
  28 + public CommonResult<String> generateAutoCode(@Valid @RequestBody MesMdAutoCodeGenerateReqVO generateReqVO) {
  29 + String code = recordService.generateAutoCode(generateReqVO.getRuleCode(), generateReqVO.getInputChar());
  30 + return success(code);
  31 + }
  32 +
  33 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/MesMdAutoCodeRuleController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRulePageReqVO;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRuleRespVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRuleSaveReqVO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  14 +import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRuleService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import jakarta.servlet.http.HttpServletResponse;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.io.IOException;
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +
  32 +@Tag(name = "管理后台 - MES 编码规则")
  33 +@RestController
  34 +@RequestMapping("/mes/auto-code-rule")
  35 +@Validated
  36 +public class MesMdAutoCodeRuleController {
  37 +
  38 + @Resource
  39 + private MesMdAutoCodeRuleService ruleService;
  40 +
  41 + @PostMapping("/create")
  42 + @Operation(summary = "创建编码规则")
  43 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:create')")
  44 + public CommonResult<Long> createAutoCodeRule(@Valid @RequestBody MesMdAutoCodeRuleSaveReqVO createReqVO) {
  45 + return success(ruleService.createAutoCodeRule(createReqVO));
  46 + }
  47 +
  48 + @PutMapping("/update")
  49 + @Operation(summary = "更新编码规则")
  50 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:update')")
  51 + public CommonResult<Boolean> updateAutoCodeRule(@Valid @RequestBody MesMdAutoCodeRuleSaveReqVO updateReqVO) {
  52 + ruleService.updateAutoCodeRule(updateReqVO);
  53 + return success(true);
  54 + }
  55 +
  56 + @DeleteMapping("/delete")
  57 + @Operation(summary = "删除编码规则")
  58 + @Parameter(name = "id", description = "编号", required = true)
  59 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:delete')")
  60 + public CommonResult<Boolean> deleteAutoCodeRule(@RequestParam("id") Long id) {
  61 + ruleService.deleteAutoCodeRule(id);
  62 + return success(true);
  63 + }
  64 +
  65 + @GetMapping("/get")
  66 + @Operation(summary = "获得编码规则")
  67 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  68 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:query')")
  69 + public CommonResult<MesMdAutoCodeRuleRespVO> getAutoCodeRule(@RequestParam("id") Long id) {
  70 + MesMdAutoCodeRuleDO rule = ruleService.getAutoCodeRule(id);
  71 + return success(BeanUtils.toBean(rule, MesMdAutoCodeRuleRespVO.class));
  72 + }
  73 +
  74 + @GetMapping("/page")
  75 + @Operation(summary = "获得编码规则分页")
  76 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:query')")
  77 + public CommonResult<PageResult<MesMdAutoCodeRuleRespVO>> getAutoCodeRulePage(@Valid MesMdAutoCodeRulePageReqVO pageReqVO) {
  78 + PageResult<MesMdAutoCodeRuleDO> pageResult = ruleService.getAutoCodeRulePage(pageReqVO);
  79 + return success(BeanUtils.toBean(pageResult, MesMdAutoCodeRuleRespVO.class));
  80 + }
  81 +
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得编码规则精简列表", description = "只包含被开启的编码规则,主要用于前端的下拉选项")
  84 + public CommonResult<List<MesMdAutoCodeRuleRespVO>> getAutoCodeRuleSimpleList() {
  85 + List<MesMdAutoCodeRuleDO> list = ruleService.getAutoCodeRuleListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + return success(convertList(list, rule -> new MesMdAutoCodeRuleRespVO()
  87 + .setId(rule.getId()).setName(rule.getName()).setCode(rule.getCode())));
  88 + }
  89 +
  90 + @GetMapping("/export-excel")
  91 + @Operation(summary = "导出编码规则 Excel")
  92 + @PreAuthorize("@ss.hasPermission('mes:auto-code-rule:export')")
  93 + @ApiAccessLog(operateType = EXPORT)
  94 + public void exportAutoCodeRuleExcel(@Valid MesMdAutoCodeRulePageReqVO pageReqVO,
  95 + HttpServletResponse response) throws IOException {
  96 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  97 + List<MesMdAutoCodeRuleDO> list = ruleService.getAutoCodeRulePage(pageReqVO).getList();
  98 + List<MesMdAutoCodeRuleRespVO> data = BeanUtils.toBean(list, MesMdAutoCodeRuleRespVO.class);
  99 + ExcelUtils.write(response, "编码规则.xls", "数据", MesMdAutoCodeRuleRespVO.class, data);
  100 + }
  101 +
  102 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/part/MesMdAutoCodePartRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  6 +import cn.idev.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +@Schema(description = "管理后台 - MES 编码规则组成 Response VO")
  13 +@Data
  14 +@ExcelIgnoreUnannotated
  15 +public class MesMdAutoCodePartRespVO {
  16 +
  17 + @Schema(description = "分段 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + @ExcelProperty("分段 ID")
  19 + private Long id;
  20 +
  21 + @Schema(description = "规则 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + @ExcelProperty("规则 ID")
  23 + private Long ruleId;
  24 +
  25 + @Schema(description = "分段序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + @ExcelProperty("分段序号")
  27 + private Integer sort;
  28 +
  29 + @Schema(description = "分段类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  30 + @ExcelProperty(value = "分段类型", converter = DictConvert.class)
  31 + @DictFormat("mes_auto_code_part_type")
  32 + private Integer type;
  33 +
  34 + @Schema(description = "分段长度", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
  35 + @ExcelProperty("分段长度")
  36 + private Integer length;
  37 +
  38 + @Schema(description = "日期格式", example = "yyyyMMdd")
  39 + @ExcelProperty("日期格式")
  40 + private String dateFormat;
  41 +
  42 + @Schema(description = "固定字符", example = "ITEM_")
  43 + @ExcelProperty("固定字符")
  44 + private String fixCharacter;
  45 +
  46 + @Schema(description = "流水号起始值", example = "1")
  47 + @ExcelProperty("流水号起始值")
  48 + private Integer serialStartNo;
  49 +
  50 + @Schema(description = "流水号步长", example = "1")
  51 + @ExcelProperty("流水号步长")
  52 + private Integer serialStep;
  53 +
  54 + @Schema(description = "流水号是否循环", example = "true")
  55 + @ExcelProperty("流水号是否循环")
  56 + private Boolean cycleFlag;
  57 +
  58 + @Schema(description = "循环方式", example = "3")
  59 + @ExcelProperty(value = "循环方式", converter = DictConvert.class)
  60 + @DictFormat("mes_auto_code_cycle_method")
  61 + private Integer cycleMethod;
  62 +
  63 + @Schema(description = "备注", example = "备注")
  64 + @ExcelProperty("备注")
  65 + private String remark;
  66 +
  67 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  68 + @ExcelProperty("创建时间")
  69 + private LocalDateTime createTime;
  70 +
  71 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/part/MesMdAutoCodePartSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - MES 编码规则组成新增/修改 Request VO")
  8 +@Data
  9 +public class MesMdAutoCodePartSaveReqVO {
  10 +
  11 + @Schema(description = "分段 ID", example = "1024")
  12 + private Long id;
  13 +
  14 + @Schema(description = "规则 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + @NotNull(message = "规则 ID 不能为空")
  16 + private Long ruleId;
  17 +
  18 + @Schema(description = "分段序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "分段序号不能为空")
  20 + private Integer sort;
  21 +
  22 + @Schema(description = "分段类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + @NotNull(message = "分段类型不能为空")
  24 + private Integer type;
  25 +
  26 + @Schema(description = "分段长度", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
  27 + @NotNull(message = "分段长度不能为空")
  28 + private Integer length;
  29 +
  30 + @Schema(description = "日期格式", example = "yyyyMMdd")
  31 + private String dateFormat;
  32 +
  33 + @Schema(description = "固定字符", example = "ITEM_")
  34 + private String fixCharacter;
  35 +
  36 + @Schema(description = "流水号起始值", example = "1")
  37 + private Integer serialStartNo;
  38 +
  39 + @Schema(description = "流水号步长", example = "1")
  40 + private Integer serialStep;
  41 +
  42 + @Schema(description = "流水号是否循环", example = "true")
  43 + private Boolean cycleFlag;
  44 +
  45 + @Schema(description = "循环方式", example = "3")
  46 + private Integer cycleMethod;
  47 +
  48 + @Schema(description = "备注", example = "备注")
  49 + private String remark;
  50 +
  51 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/record/MesMdAutoCodeGenerateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.record;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - MES 编码生成 Request VO")
  8 +@Data
  9 +public class MesMdAutoCodeGenerateReqVO {
  10 +
  11 + @Schema(description = "规则编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM_CODE")
  12 + @NotEmpty(message = "规则编码不能为空")
  13 + private String ruleCode;
  14 +
  15 + @Schema(description = "输入字符", example = "A")
  16 + private String inputChar;
  17 +
  18 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/rule/MesMdAutoCodeRulePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - MES 编码规则分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class MesMdAutoCodeRulePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "规则编码", example = "ITEM_CODE")
  21 + private String code;
  22 +
  23 + @Schema(description = "规则名称", example = "物料编码规则")
  24 + private String name;
  25 +
  26 + @Schema(description = "状态", example = "0")
  27 + private Integer status;
  28 +
  29 + @Schema(description = "创建时间")
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private LocalDateTime[] createTime;
  32 +
  33 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/rule/MesMdAutoCodeRuleRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
  6 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  7 +import cn.idev.excel.annotation.ExcelProperty;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import lombok.Data;
  10 +
  11 +import java.time.LocalDateTime;
  12 +
  13 +@Schema(description = "管理后台 - MES 编码规则 Response VO")
  14 +@Data
  15 +@ExcelIgnoreUnannotated
  16 +public class MesMdAutoCodeRuleRespVO {
  17 +
  18 + @Schema(description = "规则 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  19 + @ExcelProperty("规则 ID")
  20 + private Long id;
  21 +
  22 + @Schema(description = "规则编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM_CODE")
  23 + @ExcelProperty("规则编码")
  24 + private String code;
  25 +
  26 + @Schema(description = "规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "物料编码规则")
  27 + @ExcelProperty("规则名称")
  28 + private String name;
  29 +
  30 + @Schema(description = "描述", example = "用于生成物料编码")
  31 + @ExcelProperty("描述")
  32 + private String description;
  33 +
  34 + @Schema(description = "最大长度", example = "20")
  35 + @ExcelProperty("最大长度")
  36 + private Integer maxLength;
  37 +
  38 + @Schema(description = "是否补齐", example = "true")
  39 + @ExcelProperty("是否补齐")
  40 + private Boolean padded;
  41 +
  42 + @Schema(description = "补齐字符", example = "0")
  43 + @ExcelProperty("补齐字符")
  44 + private String paddedChar;
  45 +
  46 + @Schema(description = "补齐方式", example = "1")
  47 + @ExcelProperty(value = "补齐方式", converter = DictConvert.class)
  48 + @DictFormat("mes_auto_code_padded_method")
  49 + private Integer paddedMethod;
  50 +
  51 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  52 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  53 + @DictFormat(DictTypeConstants.COMMON_STATUS)
  54 + private Integer status;
  55 +
  56 + @Schema(description = "备注", example = "备注")
  57 + @ExcelProperty("备注")
  58 + private String remark;
  59 +
  60 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  61 + @ExcelProperty("创建时间")
  62 + private LocalDateTime createTime;
  63 +
  64 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/autocode/vo/rule/MesMdAutoCodeRuleSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "管理后台 - MES 编码规则新增/修改 Request VO")
  9 +@Data
  10 +public class MesMdAutoCodeRuleSaveReqVO {
  11 +
  12 + @Schema(description = "规则 ID", example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "规则编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM_CODE")
  16 + @NotEmpty(message = "规则编码不能为空")
  17 + private String code;
  18 +
  19 + @Schema(description = "规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "物料编码规则")
  20 + @NotEmpty(message = "规则名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "描述", example = "用于生成物料编码")
  24 + private String description;
  25 +
  26 + @Schema(description = "最大长度", example = "20")
  27 + private Integer maxLength;
  28 +
  29 + @Schema(description = "是否补齐", example = "true")
  30 + private Boolean padded;
  31 +
  32 + @Schema(description = "补齐字符", example = "0")
  33 + private String paddedChar;
  34 +
  35 + @Schema(description = "补齐方式", example = "1")
  36 + private Integer paddedMethod;
  37 +
  38 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  39 + @NotNull(message = "状态不能为空")
  40 + private Integer status;
  41 +
  42 + @Schema(description = "备注", example = "备注")
  43 + private String remark;
  44 +
  45 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodePartDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * MES 编码规则组成 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("mes_md_auto_code_part")
  15 +@KeySequence("mes_md_auto_code_part_seq")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class MesMdAutoCodePartDO extends BaseDO {
  23 +
  24 + /**
  25 + * 分段 ID
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 规则 ID
  31 + *
  32 + * 关联 {@link MesMdAutoCodeRuleDO#getId()}
  33 + */
  34 + private Long ruleId;
  35 + /**
  36 + * 分段序号
  37 + */
  38 + private Integer sort;
  39 + /**
  40 + * 分段长度
  41 + */
  42 + private Integer length;
  43 + /**
  44 + * 备注
  45 + */
  46 + private String remark;
  47 + /**
  48 + * 分段类型
  49 + *
  50 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum}
  51 + */
  52 + private Integer type;
  53 +
  54 + // ========== 当 MesMdAutoCodePartTypeEnum#INPUT_CHAR 时,使用 ==========
  55 + /**
  56 + * 固定字符
  57 + */
  58 + private String fixCharacter;
  59 +
  60 + // ========== 当 MesMdAutoCodePartTypeEnum#DATE 时,使用 ==========
  61 + /**
  62 + * 日期格式
  63 + *
  64 + * 例如:yyyyMMdd、yyyyMM、HHmmss
  65 + */
  66 + private String dateFormat;
  67 +
  68 + // ========== 当 MesMdAutoCodePartTypeEnum#SERIAL_NUMBER 时,使用 ==========
  69 + /**
  70 + * 流水号起始值
  71 + */
  72 + private Integer serialStartNo;
  73 + /**
  74 + * 流水号步长
  75 + */
  76 + private Integer serialStep;
  77 + /**
  78 + * 流水号是否循环
  79 + */
  80 + private Boolean cycleFlag;
  81 + /**
  82 + * 循环方式
  83 + *
  84 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeCycleMethodEnum}
  85 + */
  86 + private Integer cycleMethod;
  87 +
  88 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRecordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +/**
  11 + * MES 编码生成记录 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("mes_md_auto_code_record")
  16 +@KeySequence("mes_md_auto_code_record_seq")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class MesMdAutoCodeRecordDO extends BaseDO {
  24 +
  25 + /**
  26 + * 记录 ID
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 规则 ID
  32 + *
  33 + * 关联 {@link MesMdAutoCodeRuleDO#getId()}
  34 + */
  35 + private Long ruleId;
  36 + /**
  37 + * 生成的编码
  38 + */
  39 + private String result;
  40 + /**
  41 + * 生成的流水号
  42 + *
  43 + * 当规则组成中包含流水号分段({@link MesMdAutoCodePartTypeEnum#SERIAL_NUMBER})时记录,方便追溯和调试
  44 + */
  45 + private Integer serialNo;
  46 + /**
  47 + * 传入的参数
  48 + */
  49 + private String inputChar;
  50 +
  51 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRuleDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * MES 编码规则 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("mes_md_auto_code_rule")
  15 +@KeySequence("mes_md_auto_code_rule_seq")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class MesMdAutoCodeRuleDO extends BaseDO {
  23 +
  24 + /**
  25 + * 规则 ID
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 规则编码
  31 + */
  32 + private String code;
  33 + /**
  34 + * 规则名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 描述
  39 + */
  40 + private String description;
  41 + /**
  42 + * 最大长度
  43 + */
  44 + private Integer maxLength;
  45 + /**
  46 + * 是否补齐
  47 + */
  48 + private Boolean padded;
  49 + /**
  50 + * 补齐字符
  51 + */
  52 + private String paddedChar;
  53 + /**
  54 + * 补齐方式
  55 + *
  56 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePaddedMethodEnum}
  57 + */
  58 + private Integer paddedMethod;
  59 + /**
  60 + * 状态
  61 + *
  62 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  63 + */
  64 + private Integer status;
  65 + /**
  66 + * 备注
  67 + */
  68 + private String remark;
  69 +
  70 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodePartMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 编码规则组成 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesMdAutoCodePartMapper extends BaseMapperX<MesMdAutoCodePartDO> {
  17 +
  18 + default List<MesMdAutoCodePartDO> selectListByRuleId(Long ruleId) {
  19 + return selectList(new LambdaQueryWrapperX<MesMdAutoCodePartDO>()
  20 + .eq(MesMdAutoCodePartDO::getRuleId, ruleId)
  21 + .orderByAsc(MesMdAutoCodePartDO::getSort));
  22 + }
  23 +
  24 + default void deleteByRuleId(Long ruleId) {
  25 + delete(MesMdAutoCodePartDO::getRuleId, ruleId);
  26 + }
  27 +
  28 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.record.MesMdAutoCodeRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRecordDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * MES 编码生成记录 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesMdAutoCodeRecordMapper extends BaseMapperX<MesMdAutoCodeRecordDO> {
  17 +
  18 + default PageResult<MesMdAutoCodeRecordDO> selectPage(MesMdAutoCodeRecordPageReqVO reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<MesMdAutoCodeRecordDO>()
  20 + .eqIfPresent(MesMdAutoCodeRecordDO::getRuleId, reqVO.getRuleId())
  21 + .likeIfPresent(MesMdAutoCodeRecordDO::getResult, reqVO.getResult())
  22 + .betweenIfPresent(MesMdAutoCodeRecordDO::getCreateTime, reqVO.getCreateTime())
  23 + .orderByDesc(MesMdAutoCodeRecordDO::getId));
  24 + }
  25 +
  26 + default MesMdAutoCodeRecordDO selectByResult(String result) {
  27 + return selectOne(MesMdAutoCodeRecordDO::getResult, result);
  28 + }
  29 +
  30 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRuleMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRulePageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 编码规则 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface MesMdAutoCodeRuleMapper extends BaseMapperX<MesMdAutoCodeRuleDO> {
  19 +
  20 + default PageResult<MesMdAutoCodeRuleDO> selectPage(MesMdAutoCodeRulePageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<MesMdAutoCodeRuleDO>()
  22 + .likeIfPresent(MesMdAutoCodeRuleDO::getCode, reqVO.getCode())
  23 + .likeIfPresent(MesMdAutoCodeRuleDO::getName, reqVO.getName())
  24 + .eqIfPresent(MesMdAutoCodeRuleDO::getStatus, reqVO.getStatus())
  25 + .betweenIfPresent(MesMdAutoCodeRuleDO::getCreateTime, reqVO.getCreateTime())
  26 + .orderByDesc(MesMdAutoCodeRuleDO::getId));
  27 + }
  28 +
  29 + default MesMdAutoCodeRuleDO selectByCode(String code) {
  30 + return selectOne(MesMdAutoCodeRuleDO::getCode, code);
  31 + }
  32 +
  33 + default List<MesMdAutoCodeRuleDO> selectListByStatus(Integer status) {
  34 + return selectList(MesMdAutoCodeRuleDO::getStatus, status);
  35 + }
  36 +
  37 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/RedisKeyConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.redis;
  2 +
  3 +/**
  4 + * MES Redis Key 枚举类
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface RedisKeyConstants {
  9 +
  10 + /**
  11 + * 编码规则的缓存
  12 + *
  13 + * KEY 格式:mes:md:auto_code:{ruleId}:{cycleKey}
  14 + * VALUE 数据格式:流水号自增
  15 + */
  16 + String AUTO_CODE = "mes:md:auto_code:";
  17 +
  18 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.redis.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.redis.RedisKeyConstants;
  4 +import jakarta.annotation.Resource;
  5 +import org.springframework.data.redis.core.StringRedisTemplate;
  6 +import org.springframework.stereotype.Repository;
  7 +
  8 +import java.time.Duration;
  9 +
  10 +/**
  11 + * MES 编码规则的 Redis DAO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Repository
  16 +public class MesMdAutoCodeRedisDAO {
  17 +
  18 + @Resource
  19 + private StringRedisTemplate stringRedisTemplate;
  20 +
  21 + /**
  22 + * 递增序号(带循环)
  23 + *
  24 + * @param keySuffix key 后缀(不包含 prefix)
  25 + * @param duration 过期时间
  26 + * @param step 步长
  27 + * @return 递增后的值
  28 + */
  29 + public Long increment(String keySuffix, Duration duration, Integer step) {
  30 + // 递增值
  31 + String key = RedisKeyConstants.AUTO_CODE + keySuffix;
  32 + Long value = stringRedisTemplate.opsForValue().increment(key, step);
  33 +
  34 + // 设置过期时间
  35 + if (duration != null) {
  36 + stringRedisTemplate.expire(key, duration);
  37 + }
  38 + return value;
  39 + }
  40 +
  41 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -82,6 +82,14 @@ public interface ErrorCodeConstants {
82 82 ErrorCode MD_PRODUCT_SIP_NOT_EXISTS = new ErrorCode(1_040_109_000, "产品SIP不存在");
83 83 ErrorCode MD_PRODUCT_SIP_SORT_DUPLICATE = new ErrorCode(1_040_109_001, "该展示序号已存在");
84 84  
  85 + // ========== MES 基础数据-编码规则(1-040-110-000) ==========
  86 + ErrorCode AUTO_CODE_RULE_NOT_EXISTS = new ErrorCode(1_040_110_000, "编码规则不存在");
  87 + ErrorCode AUTO_CODE_RULE_CODE_DUPLICATE = new ErrorCode(1_040_110_001, "规则编码已存在");
  88 + ErrorCode AUTO_CODE_PART_NOT_EXISTS = new ErrorCode(1_040_110_002, "规则组成不存在");
  89 + ErrorCode AUTO_CODE_REDIS_ERROR = new ErrorCode(1_040_110_003, "编码生成服务不可用,请稍后重试");
  90 + ErrorCode AUTO_CODE_GENERATE_FAILED = new ErrorCode(1_040_110_004, "编码生成失败");
  91 + ErrorCode AUTO_CODE_PART_SERIAL_NUMBER_DUPLICATE = new ErrorCode(1_040_110_005, "流水号分段只能存在一个");
  92 +
85 93 // ========== MES 日历排班-计划班次(1-040-200-000) ==========
86 94 ErrorCode CAL_PLAN_SHIFT_NOT_EXISTS = new ErrorCode(1_040_200_000, "计划班次不存在");
87 95 ErrorCode CAL_PLAN_SHIFT_COUNT_EXCEED = new ErrorCode(1_040_200_001, "班次数量已达到轮班方式的上限");
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeCycleMethodEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 编码规则循环方式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesMdAutoCodeCycleMethodEnum implements ArrayValuable<Integer> {
  17 +
  18 + YEAR(1, "按年"),
  19 + MONTH(2, "按月"),
  20 + DAY(3, "按天"),
  21 + HOUR(4, "按小时"),
  22 + MINUTE(5, "按分钟"),
  23 + INPUT_CHAR(10, "按传入字符");
  24 +
  25 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodeCycleMethodEnum::getMethod).toArray(Integer[]::new);
  26 +
  27 + /**
  28 + * 方式
  29 + */
  30 + private final Integer method;
  31 + /**
  32 + * 名称
  33 + */
  34 + private final String name;
  35 +
  36 + @Override
  37 + public Integer[] array() {
  38 + return ARRAYS;
  39 + }
  40 +
  41 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePaddedMethodEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 编码规则补齐方式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesMdAutoCodePaddedMethodEnum implements ArrayValuable<Integer> {
  17 +
  18 + LEFT(1, "左补齐"),
  19 + RIGHT(2, "右补齐");
  20 +
  21 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodePaddedMethodEnum::getMethod).toArray(Integer[]::new);
  22 +
  23 + /**
  24 + * 方式
  25 + */
  26 + private final Integer method;
  27 + /**
  28 + * 名称
  29 + */
  30 + private final String name;
  31 +
  32 + @Override
  33 + public Integer[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePartTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 编码规则分段类型枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesMdAutoCodePartTypeEnum implements ArrayValuable<Integer> {
  17 +
  18 + INPUT_CHAR(1, "输入字符"),
  19 + DATE(2, "当前日期"),
  20 + FIXED_CHAR(3, "固定字符"),
  21 + SERIAL_NUMBER(4, "流水号");
  22 +
  23 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodePartTypeEnum::getType).toArray(Integer[]::new);
  24 +
  25 + /**
  26 + * 类型
  27 + */
  28 + private final Integer type;
  29 + /**
  30 + * 名称
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public Integer[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodePartService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAutoCodePartSaveReqVO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 编码规则组成 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesMdAutoCodePartService {
  15 +
  16 + /**
  17 + * 创建规则组成
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createAutoCodePart(@Valid MesMdAutoCodePartSaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 更新规则组成
  26 + *
  27 + * @param updateReqVO 更新信息
  28 + */
  29 + void updateAutoCodePart(@Valid MesMdAutoCodePartSaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除规则组成
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void deleteAutoCodePart(Long id);
  37 +
  38 + /**
  39 + * 获得规则组成
  40 + *
  41 + * @param id 编号
  42 + * @return 规则组成
  43 + */
  44 + MesMdAutoCodePartDO getAutoCodePart(Long id);
  45 +
  46 + /**
  47 + * 获得规则组成列表(根据规则 ID)
  48 + *
  49 + * @param ruleId 规则 ID
  50 + * @return 规则组成列表
  51 + */
  52 + List<MesMdAutoCodePartDO> getAutoCodePartListByRuleId(Long ruleId);
  53 +
  54 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodePartServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +import cn.hutool.core.util.ObjUtil;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAutoCodePartSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  7 +import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodePartMapper;
  8 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  16 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.AUTO_CODE_PART_NOT_EXISTS;
  17 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.AUTO_CODE_PART_SERIAL_NUMBER_DUPLICATE;
  18 +
  19 +/**
  20 + * MES 编码规则组成 Service 实现类
  21 + *
  22 + * @author 芋道源码
  23 + */
  24 +@Service
  25 +@Validated
  26 +public class MesMdAutoCodePartServiceImpl implements MesMdAutoCodePartService {
  27 +
  28 + @Resource
  29 + private MesMdAutoCodePartMapper partMapper;
  30 +
  31 + @Resource
  32 + private MesMdAutoCodeRuleService ruleService;
  33 +
  34 + @Override
  35 + public Long createAutoCodePart(MesMdAutoCodePartSaveReqVO createReqVO) {
  36 + // 校验规则存在
  37 + ruleService.validateAutoCodeRuleExists(createReqVO.getRuleId());
  38 + // 校验流水号分段唯一性
  39 + validateSerialNumberPartUnique(null, createReqVO.getRuleId(), createReqVO.getType());
  40 +
  41 + // 插入
  42 + MesMdAutoCodePartDO part = BeanUtils.toBean(createReqVO, MesMdAutoCodePartDO.class);
  43 + partMapper.insert(part);
  44 + return part.getId();
  45 + }
  46 +
  47 + @Override
  48 + public void updateAutoCodePart(MesMdAutoCodePartSaveReqVO updateReqVO) {
  49 + // 校验存在
  50 + validatePartExists(updateReqVO.getId());
  51 + // 校验规则存在
  52 + ruleService.validateAutoCodeRuleExists(updateReqVO.getRuleId());
  53 + // 校验流水号分段唯一性
  54 + validateSerialNumberPartUnique(updateReqVO.getId(), updateReqVO.getRuleId(), updateReqVO.getType());
  55 +
  56 + // 更新
  57 + MesMdAutoCodePartDO updateObj = BeanUtils.toBean(updateReqVO, MesMdAutoCodePartDO.class);
  58 + partMapper.updateById(updateObj);
  59 + }
  60 +
  61 + @Override
  62 + public void deleteAutoCodePart(Long id) {
  63 + // 校验存在
  64 + validatePartExists(id);
  65 +
  66 + // 删除
  67 + partMapper.deleteById(id);
  68 + }
  69 +
  70 + @Override
  71 + public MesMdAutoCodePartDO getAutoCodePart(Long id) {
  72 + return partMapper.selectById(id);
  73 + }
  74 +
  75 + @Override
  76 + public List<MesMdAutoCodePartDO> getAutoCodePartListByRuleId(Long ruleId) {
  77 + return partMapper.selectListByRuleId(ruleId);
  78 + }
  79 +
  80 + // ==================== 校验方法 ====================
  81 +
  82 + private void validatePartExists(Long id) {
  83 + if (partMapper.selectById(id) == null) {
  84 + throw exception(AUTO_CODE_PART_NOT_EXISTS);
  85 + }
  86 + }
  87 +
  88 + private void validateSerialNumberPartUnique(Long id, Long ruleId, Integer type) {
  89 + // 只有流水号类型才需要校验
  90 + if (ObjUtil.notEqual(MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType(), type)) {
  91 + return;
  92 + }
  93 + // 查询该规则下所有流水号分段
  94 + List<MesMdAutoCodePartDO> parts = partMapper.selectListByRuleId(ruleId);
  95 + long count = parts.stream()
  96 + .filter(part -> MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType().equals(part.getType()))
  97 + .filter(part -> ObjUtil.notEqual(id, part.getId())) // 排除自己
  98 + .count();
  99 + if (count > 0) {
  100 + throw exception(AUTO_CODE_PART_SERIAL_NUMBER_DUPLICATE);
  101 + }
  102 + }
  103 +
  104 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +/**
  4 + * MES 编码生成记录 Service 接口
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface MesMdAutoCodeRecordService {
  9 +
  10 + /**
  11 + * 生成编码
  12 + *
  13 + * @param ruleCode 规则编码
  14 + * @param inputChar 输入字符
  15 + * @return 生成的编码
  16 + */
  17 + String generateAutoCode(String ruleCode, String inputChar);
  18 +
  19 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRecordDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  10 +import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodeRecordMapper;
  11 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePaddedMethodEnum;
  12 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext;
  13 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy;
  14 +import jakarta.annotation.PostConstruct;
  15 +import jakarta.annotation.Resource;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.annotation.Transactional;
  18 +import org.springframework.validation.annotation.Validated;
  19 +
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  24 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  25 +
  26 +/**
  27 + * MES 编码生成记录 Service 实现类
  28 + *
  29 + * @author 芋道源码
  30 + */
  31 +@Service
  32 +@Validated
  33 +public class MesMdAutoCodeRecordServiceImpl implements MesMdAutoCodeRecordService {
  34 +
  35 + @Resource
  36 + private MesMdAutoCodeRecordMapper recordMapper;
  37 +
  38 + @Resource
  39 + private MesMdAutoCodeRuleService ruleService;
  40 + @Resource
  41 + private MesMdAutoCodePartService partService;
  42 +
  43 + @Resource
  44 + private List<MesMdAutoCodePartStrategy> strategyList;
  45 + private Map<Integer, MesMdAutoCodePartStrategy> strategyMap;
  46 +
  47 + @PostConstruct
  48 + public void init() {
  49 + strategyMap = CollectionUtils.convertMap(strategyList, MesMdAutoCodePartStrategy::getType);
  50 + }
  51 +
  52 + @Override
  53 + @Transactional(rollbackFor = Exception.class)
  54 + public String generateAutoCode(String ruleCode, String inputChar) {
  55 + // 1.1 查询规则
  56 + MesMdAutoCodeRuleDO rule = ruleService.getAutoCodeRuleByCode(ruleCode);
  57 + if (rule == null) {
  58 + throw exception(AUTO_CODE_RULE_NOT_EXISTS);
  59 + }
  60 + // 1.2 查询规则组成
  61 + List<MesMdAutoCodePartDO> parts = partService.getAutoCodePartListByRuleId(rule.getId());
  62 + if (CollUtil.isEmpty(parts)) {
  63 + throw exception(AUTO_CODE_GENERATE_FAILED);
  64 + }
  65 +
  66 + // 2.1 构建上下文
  67 + MesMdAutoCodeContext context = new MesMdAutoCodeContext()
  68 + .setRule(rule).setParts(parts).setInputChar(inputChar);
  69 + // 2.2 遍历分段,生成编码
  70 + StringBuilder codeBuilder = new StringBuilder();
  71 + for (MesMdAutoCodePartDO part : parts) {
  72 + MesMdAutoCodePartStrategy strategy = strategyMap.get(part.getType());
  73 + Assert.notNull(strategy, () -> exception(AUTO_CODE_GENERATE_FAILED));
  74 + // 生成分段编码
  75 + String partCode = strategy.generate(part, context);
  76 + // 统一截取指定长度
  77 + partCode = StrUtil.sub(partCode, 0, part.getLength());
  78 + // 拼接分段编码
  79 + codeBuilder.append(partCode);
  80 + }
  81 + // 2.3 补齐处理
  82 + String result = codeBuilder.toString();
  83 + if (Boolean.TRUE.equals(rule.getPadded()) && rule.getMaxLength() != null) {
  84 + result = padCode(result, rule);
  85 + }
  86 +
  87 + // 3.1 二次校验(防止重复)
  88 + MesMdAutoCodeRecordDO existRecord = recordMapper.selectByResult(result);
  89 + if (existRecord != null) {
  90 + throw exception(AUTO_CODE_GENERATE_FAILED);
  91 + }
  92 + // 3.2 保存生成记录
  93 + MesMdAutoCodeRecordDO record = new MesMdAutoCodeRecordDO()
  94 + .setRuleId(rule.getId()).setResult(result)
  95 + .setSerialNo(context.getSerialNo()).setInputChar(inputChar);
  96 + recordMapper.insert(record);
  97 + return result;
  98 + }
  99 +
  100 + /**
  101 + * 补齐编码
  102 + */
  103 + private String padCode(String code, MesMdAutoCodeRuleDO rule) {
  104 + if (code.length() >= rule.getMaxLength()) {
  105 + return StrUtil.sub(code, 0, rule.getMaxLength());
  106 + }
  107 + String paddedChar = StrUtil.emptyToDefault(rule.getPaddedChar(), "0");
  108 + Integer paddedMethod = rule.getPaddedMethod() != null ? rule.getPaddedMethod() : MesMdAutoCodePaddedMethodEnum.LEFT.getMethod();
  109 + if (MesMdAutoCodePaddedMethodEnum.LEFT.getMethod().equals(paddedMethod)) {
  110 + // 左补齐
  111 + return StrUtil.padPre(code, rule.getMaxLength(), paddedChar.charAt(0));
  112 + } else {
  113 + // 右补齐
  114 + return StrUtil.padAfter(code, rule.getMaxLength(), paddedChar.charAt(0));
  115 + }
  116 + }
  117 +
  118 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRuleService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRulePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRuleSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * MES 编码规则 Service 接口
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public interface MesMdAutoCodeRuleService {
  17 +
  18 + /**
  19 + * 创建编码规则
  20 + *
  21 + * @param createReqVO 创建信息
  22 + * @return 编号
  23 + */
  24 + Long createAutoCodeRule(@Valid MesMdAutoCodeRuleSaveReqVO createReqVO);
  25 +
  26 + /**
  27 + * 更新编码规则
  28 + *
  29 + * @param updateReqVO 更新信息
  30 + */
  31 + void updateAutoCodeRule(@Valid MesMdAutoCodeRuleSaveReqVO updateReqVO);
  32 +
  33 + /**
  34 + * 删除编码规则
  35 + *
  36 + * @param id 编号
  37 + */
  38 + void deleteAutoCodeRule(Long id);
  39 +
  40 + /**
  41 + * 获得编码规则
  42 + *
  43 + * @param id 编号
  44 + * @return 编码规则
  45 + */
  46 + MesMdAutoCodeRuleDO getAutoCodeRule(Long id);
  47 +
  48 + /**
  49 + * 获得编码规则分页
  50 + *
  51 + * @param pageReqVO 分页查询
  52 + * @return 编码规则分页
  53 + */
  54 + PageResult<MesMdAutoCodeRuleDO> getAutoCodeRulePage(MesMdAutoCodeRulePageReqVO pageReqVO);
  55 +
  56 + /**
  57 + * 获得编码规则列表(根据状态)
  58 + *
  59 + * @param status 状态
  60 + * @return 编码规则列表
  61 + */
  62 + List<MesMdAutoCodeRuleDO> getAutoCodeRuleListByStatus(Integer status);
  63 +
  64 + /**
  65 + * 根据规则编码获取规则
  66 + *
  67 + * @param code 规则编码
  68 + * @return 编码规则
  69 + */
  70 + MesMdAutoCodeRuleDO getAutoCodeRuleByCode(String code);
  71 +
  72 + /**
  73 + * 校验编码规则是否存在
  74 + *
  75 + * @param id 编号
  76 + */
  77 + void validateAutoCodeRuleExists(Long id);
  78 +
  79 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRuleServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode;
  2 +
  3 +import cn.hutool.core.util.ObjUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRulePageReqVO;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.rule.MesMdAutoCodeRuleSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  9 +import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodePartMapper;
  10 +import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodeRuleMapper;
  11 +import jakarta.annotation.Resource;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.transaction.annotation.Transactional;
  14 +import org.springframework.validation.annotation.Validated;
  15 +
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  20 +
  21 +/**
  22 + * MES 编码规则 Service 实现类
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +@Service
  27 +@Validated
  28 +public class MesMdAutoCodeRuleServiceImpl implements MesMdAutoCodeRuleService {
  29 +
  30 + @Resource
  31 + private MesMdAutoCodeRuleMapper ruleMapper;
  32 +
  33 + @Resource
  34 + private MesMdAutoCodePartMapper partMapper;
  35 +
  36 + @Override
  37 + public Long createAutoCodeRule(MesMdAutoCodeRuleSaveReqVO createReqVO) {
  38 + // 校验规则编码的唯一性
  39 + validateRuleCodeUnique(null, createReqVO.getCode());
  40 +
  41 + // 插入
  42 + MesMdAutoCodeRuleDO rule = BeanUtils.toBean(createReqVO, MesMdAutoCodeRuleDO.class);
  43 + ruleMapper.insert(rule);
  44 + return rule.getId();
  45 + }
  46 +
  47 + @Override
  48 + public void updateAutoCodeRule(MesMdAutoCodeRuleSaveReqVO updateReqVO) {
  49 + // 校验存在
  50 + validateAutoCodeRuleExists(updateReqVO.getId());
  51 + // 校验规则编码的唯一性
  52 + validateRuleCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
  53 +
  54 + // 更新
  55 + MesMdAutoCodeRuleDO updateObj = BeanUtils.toBean(updateReqVO, MesMdAutoCodeRuleDO.class);
  56 + ruleMapper.updateById(updateObj);
  57 + }
  58 +
  59 + @Override
  60 + @Transactional(rollbackFor = Exception.class)
  61 + public void deleteAutoCodeRule(Long id) {
  62 + // 校验存在
  63 + validateAutoCodeRuleExists(id);
  64 +
  65 + // 删除规则
  66 + ruleMapper.deleteById(id);
  67 + // 级联删除规则组成
  68 + partMapper.deleteByRuleId(id);
  69 + }
  70 +
  71 + @Override
  72 + public MesMdAutoCodeRuleDO getAutoCodeRule(Long id) {
  73 + return ruleMapper.selectById(id);
  74 + }
  75 +
  76 + @Override
  77 + public PageResult<MesMdAutoCodeRuleDO> getAutoCodeRulePage(MesMdAutoCodeRulePageReqVO pageReqVO) {
  78 + return ruleMapper.selectPage(pageReqVO);
  79 + }
  80 +
  81 + @Override
  82 + public List<MesMdAutoCodeRuleDO> getAutoCodeRuleListByStatus(Integer status) {
  83 + return ruleMapper.selectListByStatus(status);
  84 + }
  85 +
  86 + @Override
  87 + public MesMdAutoCodeRuleDO getAutoCodeRuleByCode(String code) {
  88 + return ruleMapper.selectByCode(code);
  89 + }
  90 +
  91 + @Override
  92 + public void validateAutoCodeRuleExists(Long id) {
  93 + if (ruleMapper.selectById(id) == null) {
  94 + throw exception(AUTO_CODE_RULE_NOT_EXISTS);
  95 + }
  96 + }
  97 +
  98 + // ==================== 校验方法 ====================
  99 +
  100 + private void validateRuleCodeUnique(Long id, String code) {
  101 + MesMdAutoCodeRuleDO rule = ruleMapper.selectByCode(code);
  102 + if (rule == null) {
  103 + return;
  104 + }
  105 + if (ObjUtil.notEqual(id, rule.getId())) {
  106 + throw exception(AUTO_CODE_RULE_CODE_DUPLICATE);
  107 + }
  108 + }
  109 +
  110 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 编码生成上下文
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class MesMdAutoCodeContext {
  16 +
  17 + /**
  18 + * 规则
  19 + */
  20 + private MesMdAutoCodeRuleDO rule;
  21 + /**
  22 + * 规则组成列表
  23 + */
  24 + private List<MesMdAutoCodePartDO> parts;
  25 +
  26 + /**
  27 + * 输入字符
  28 + */
  29 + private String inputChar;
  30 +
  31 + /**
  32 + * 流水号
  33 + *
  34 + * 由流水号策略生成并设置,用于保存到生成记录表。例如:当规则包含流水号分段时,生成编码 "ITEM_20260304_0001",此字段值为 1
  35 + */
  36 + private Integer serialNo;
  37 +
  38 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodePartStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  4 +
  5 +/**
  6 + * MES 编码规则分段策略接口
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public interface MesMdAutoCodePartStrategy {
  11 +
  12 + /**
  13 + * 获取策略类型
  14 + *
  15 + * @return 分段类型
  16 + */
  17 + Integer getType();
  18 +
  19 + /**
  20 + * 生成分段内容
  21 + *
  22 + * @param part 规则组成
  23 + * @param context 上下文
  24 + * @return 分段内容
  25 + */
  26 + String generate(MesMdAutoCodePartDO part, MesMdAutoCodeContext context);
  27 +
  28 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl;
  2 +
  3 +import cn.hutool.core.date.DatePattern;
  4 +import cn.hutool.core.date.DateUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  7 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  8 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext;
  9 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy;
  10 +import org.springframework.stereotype.Component;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +/**
  15 + * MES 编码规则 - 当前日期策略
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Component
  20 +public class MesMdAutoCodeDatePartStrategy implements MesMdAutoCodePartStrategy {
  21 +
  22 + @Override
  23 + public Integer getType() {
  24 + return MesMdAutoCodePartTypeEnum.DATE.getType();
  25 + }
  26 +
  27 + @Override
  28 + public String generate(MesMdAutoCodePartDO part, MesMdAutoCodeContext context) {
  29 + String dateFormat = StrUtil.emptyToDefault(part.getDateFormat(), DatePattern.PURE_DATE_PATTERN);
  30 + return DateUtil.format(LocalDateTime.now(), dateFormat);
  31 + }
  32 +
  33 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  5 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  6 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext;
  7 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * MES 编码规则 - 固定字符策略
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +public class MesMdAutoCodeFixedCharPartStrategy implements MesMdAutoCodePartStrategy {
  17 +
  18 + @Override
  19 + public Integer getType() {
  20 + return MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType();
  21 + }
  22 +
  23 + @Override
  24 + public String generate(MesMdAutoCodePartDO part, MesMdAutoCodeContext context) {
  25 + return StrUtil.emptyToDefault(part.getFixCharacter(), "");
  26 + }
  27 +
  28 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  5 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  6 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext;
  7 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * MES 编码规则 - 输入字符策略
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +public class MesMdAutoCodeInputCharPartStrategy implements MesMdAutoCodePartStrategy {
  17 +
  18 + @Override
  19 + public Integer getType() {
  20 + return MesMdAutoCodePartTypeEnum.INPUT_CHAR.getType();
  21 + }
  22 +
  23 + @Override
  24 + public String generate(MesMdAutoCodePartDO part, MesMdAutoCodeContext context) {
  25 + String inputChar = context.getInputChar();
  26 + return StrUtil.emptyToDefault(inputChar, "");
  27 + }
  28 +
  29 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl;
  2 +
  3 +import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO;
  6 +import cn.iocoder.yudao.module.mes.dal.redis.md.autocode.MesMdAutoCodeRedisDAO;
  7 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeCycleMethodEnum;
  8 +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum;
  9 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext;
  10 +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy;
  11 +import jakarta.annotation.Resource;
  12 +import org.springframework.stereotype.Component;
  13 +
  14 +import java.time.Duration;
  15 +import java.time.LocalDateTime;
  16 +
  17 +/**
  18 + * MES 编码规则 - 流水号策略
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Component
  23 +public class MesMdAutoCodeSerialNumberPartStrategy implements MesMdAutoCodePartStrategy {
  24 +
  25 + @Resource
  26 + private MesMdAutoCodeRedisDAO redisDAO;
  27 +
  28 + @Override
  29 + public Integer getType() {
  30 + return MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType();
  31 + }
  32 +
  33 + @Override
  34 + public String generate(MesMdAutoCodePartDO part, MesMdAutoCodeContext context) {
  35 + // 1.1 构建 Redis key 后缀
  36 + String keySuffix = buildRedisKeySuffix(part, context);
  37 + // 1.2 获取过期时间
  38 + Duration duration = Boolean.TRUE.equals(part.getCycleFlag()) ? getExpireDuration(part.getCycleMethod()) : null;
  39 +
  40 + // 2.1 获取流水号
  41 + Integer step = part.getSerialStep() != null ? part.getSerialStep() : 1;
  42 + Long serialNo = redisDAO.increment(keySuffix, duration, step);
  43 + // 2.2 保存流水号到上下文
  44 + context.setSerialNo(serialNo.intValue());
  45 +
  46 + // 3. 格式化输出(补零)
  47 + String serialStr = String.valueOf(serialNo);
  48 + if (serialStr.length() < part.getLength()) {
  49 + serialStr = StrUtil.padPre(serialStr, part.getLength(), '0');
  50 + }
  51 + return serialStr;
  52 + }
  53 +
  54 + /**
  55 + * 构建 Redis key 后缀
  56 + */
  57 + private String buildRedisKeySuffix(MesMdAutoCodePartDO part, MesMdAutoCodeContext context) {
  58 + StringBuilder keySuffix = new StringBuilder();
  59 + keySuffix.append(context.getRule().getId());
  60 +
  61 + // 如果不循环,直接返回
  62 + if (!Boolean.TRUE.equals(part.getCycleFlag()) || part.getCycleMethod() == null) {
  63 + return keySuffix.toString();
  64 + }
  65 +
  66 + // 根据循环方式构建 key 后缀
  67 + keySuffix.append(":");
  68 + LocalDateTime time = LocalDateTime.now();
  69 + if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.YEAR.getMethod())) {
  70 + keySuffix.append(DateUtil.format(time, "yyyy"));
  71 + } else if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.MONTH.getMethod())) {
  72 + keySuffix.append(DateUtil.format(time, "yyyyMM"));
  73 + } else if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.DAY.getMethod())) {
  74 + keySuffix.append(DateUtil.format(time, "yyyyMMdd"));
  75 + } else if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.HOUR.getMethod())) {
  76 + keySuffix.append(DateUtil.format(time, "yyyyMMddHH"));
  77 + } else if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.MINUTE.getMethod())) {
  78 + keySuffix.append(DateUtil.format(time, "yyyyMMddHHmm"));
  79 + } else if (part.getCycleMethod().equals(MesMdAutoCodeCycleMethodEnum.INPUT_CHAR.getMethod())) {
  80 + if (StrUtil.isNotEmpty(context.getInputChar())) {
  81 + keySuffix.append(context.getInputChar());
  82 + }
  83 + } else {
  84 + throw new IllegalArgumentException("未知的循环方式:" + part.getCycleMethod());
  85 + }
  86 + return keySuffix.toString();
  87 + }
  88 +
  89 + /**
  90 + * 获取过期时间
  91 + */
  92 + private Duration getExpireDuration(Integer cycleMethod) {
  93 + if (cycleMethod == null) {
  94 + return Duration.ofDays(1);
  95 + }
  96 + if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.YEAR.getMethod())) {
  97 + return Duration.ofDays(366);
  98 + } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.MONTH.getMethod())) {
  99 + return Duration.ofDays(32);
  100 + } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.DAY.getMethod())) {
  101 + return Duration.ofDays(2);
  102 + } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.HOUR.getMethod())) {
  103 + return Duration.ofHours(2);
  104 + } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.MINUTE.getMethod())) {
  105 + return Duration.ofMinutes(2);
  106 + } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.INPUT_CHAR.getMethod())) {
  107 + return Duration.ofDays(30);
  108 + } else {
  109 + throw new IllegalArgumentException("未知的循环方式:" + cycleMethod);
  110 + }
  111 + }
  112 +
  113 +}
... ...