From fc2d27ba63f5c4b7bc9aab3b458735640f95e214 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 5 Mar 2026 13:36:35 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(mes):=20=E6=B7=BB=E5=8A=A0=20S?= =?UTF-8?q?N=20=E7=A0=81=E7=94=9F=E6=88=90=E3=80=81=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=92=8C=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 SN 码生成、分页查询和批量删除的 API 接口,支持导出 SN 码分组和明细为 Excel 文件。实现了前端页面的搜索、生成和导出功能,提升了用户操作的便捷性。 --- .../admin/wm/sn/MesWmSnController.java | 119 +++++++++ .../admin/wm/sn/vo/MesWmSnGenerateReqVO.java | 31 +++ .../admin/wm/sn/vo/MesWmSnGroupRespVO.java | 48 ++++ .../admin/wm/sn/vo/MesWmSnPageReqVO.java | 36 +++ .../admin/wm/sn/vo/MesWmSnRespVO.java | 51 ++++ .../mes/dal/dataobject/wm/sn/MesWmSnDO.java | 57 ++++ .../mes/dal/mysql/wm/sn/MesWmSnMapper.java | 54 ++++ .../autocode/MesMdAutoCodeRuleCodeEnum.java | 26 ++ .../autocode/MesMdAutoCodeRecordService.java | 10 + .../mes/service/wm/sn/MesWmSnService.java | 48 ++++ .../mes/service/wm/sn/MesWmSnServiceImpl.java | 69 +++++ .../src/api/mes/wm/sn/index.ts | 45 ++++ .../src/views/mes/wm/sn/index.vue | 248 ++++++++++++++++++ 13 files changed, 842 insertions(+) create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGenerateReqVO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGroupRespVO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnPageReqVO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnRespVO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/sn/MesWmSnDO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/sn/MesWmSnMapper.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnService.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java create mode 100644 yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/sn/index.ts create mode 100644 yudao-ui/yudao-ui-admin-vue3/src/views/mes/wm/sn/index.vue diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java new file mode 100644 index 0000000000..e9c19b489f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.sn; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnRespVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.wm.sn.MesWmSnService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - MES SN 码") +@RestController +@RequestMapping("/mes/wm/sn") +@Validated +public class MesWmSnController { + + @Resource + private MesWmSnService snService; + @Resource + private MesMdItemService itemService; + + @PostMapping("/generate") + @Operation(summary = "生成 SN 码") + @PreAuthorize("@ss.hasPermission('mes:wm-sn:create')") + public CommonResult generateSnCodes(@Valid @RequestBody MesWmSnGenerateReqVO reqVO) { + snService.generateSnCodes(reqVO); + return success(true); + } + + @GetMapping("/group-page") + @Operation(summary = "获得 SN 码分组分页") + @PreAuthorize("@ss.hasPermission('mes:wm-sn:query')") + public CommonResult> getSnGroupPage(@Valid MesWmSnPageReqVO reqVO) { + PageResult pageResult = snService.getSnGroupPage(reqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty(pageResult.getTotal())); + } + buildGroupItemInfo(pageResult.getList()); + return success(pageResult); + } + + @DeleteMapping("/delete-batch") + @Operation(summary = "批量删除 SN 码(按批次 UUID)") + @Parameter(name = "uuid", description = "批次 UUID", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-sn:delete')") + public CommonResult deleteSnBatch(@RequestParam("uuid") @NotBlank(message = "批次 UUID 不能为空") String uuid) { + snService.deleteSnByUuid(uuid); + return success(true); + } + + @GetMapping("/group-export-excel") + @Operation(summary = "导出 SN 码分组 Excel") + @PreAuthorize("@ss.hasPermission('mes:wm-sn:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportSnGroupExcel(@Valid MesWmSnPageReqVO reqVO, HttpServletResponse response) throws IOException { + reqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = snService.getSnGroupPage(reqVO).getList(); + buildGroupItemInfo(list); + ExcelUtils.write(response, "SN码分组.xls", "数据", MesWmSnGroupRespVO.class, list); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出批次 SN 码明细 Excel") + @Parameter(name = "uuid", description = "批次 UUID", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-sn:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportSnExcel(@RequestParam("uuid") String uuid, HttpServletResponse response) throws IOException { + List list = BeanUtils.toBean(snService.getSnListByUuid(uuid), MesWmSnRespVO.class); + buildItemInfo(list); + ExcelUtils.write(response, "SN码明细.xls", "数据", MesWmSnRespVO.class, list); + } + + // ==================== 拼接 VO ==================== + + private void buildGroupItemInfo(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + Map itemMap = itemService.getItemMap(convertSet(list, MesWmSnGroupRespVO::getItemId)); + list.forEach(vo -> MapUtils.findAndThen(itemMap, vo.getItemId(), item -> + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()))); + } + + private void buildItemInfo(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + Map itemMap = itemService.getItemMap(convertSet(list, MesWmSnRespVO::getItemId)); + list.forEach(vo -> MapUtils.findAndThen(itemMap, vo.getItemId(), item -> + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()))); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGenerateReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGenerateReqVO.java new file mode 100644 index 0000000000..039c56eaf4 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGenerateReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; + +@Schema(description = "管理后台 - MES SN 码生成 Request VO") +@Data +public class MesWmSnGenerateReqVO { + + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "物料编号不能为空") + private Long itemId; + + @Schema(description = "批次号", example = "BATCH001") + @Size(max = 100, message = "批次号长度不能超过 100 个字符") + private String batchCode; + + @Schema(description = "生产工单编号", example = "1") + private Long workOrderId; + + @Schema(description = "生成数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "生成数量不能为空") + @Min(value = 1, message = "生成数量最小为 1") + @Max(value = 1000, message = "生成数量最大为 1000") + private Integer count; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGroupRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGroupRespVO.java new file mode 100644 index 0000000000..ed28830509 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnGroupRespVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES SN 码分组 Response VO") +@Data +@Accessors(chain = true) +public class MesWmSnGroupRespVO { + + @Schema(description = "批次 UUID", example = "550e8400-e29b-41d4-a716-446655440000") + private String uuid; + + @Schema(description = "SN 码数量", example = "100") + @ExcelProperty("SN 码数量") + private Integer count; + + @Schema(description = "物料编号", example = "1") + private Long itemId; + + @Schema(description = "物料编码", example = "ITEM001") + @ExcelProperty("物料编码") + private String itemCode; + + @Schema(description = "物料名称", example = "物料A") + @ExcelProperty("物料名称") + private String itemName; + + @Schema(description = "规格型号", example = "100*200") + @ExcelProperty("规格型号") + private String specification; + + @Schema(description = "批次号", example = "BATCH001") + @ExcelProperty("批次号") + private String batchCode; + + @Schema(description = "生产工单编号", example = "1") + private Long workOrderId; + + @Schema(description = "创建时间") + @ExcelProperty("生成时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnPageReqVO.java new file mode 100644 index 0000000000..6578e2e257 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnPageReqVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - MES SN 码分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MesWmSnPageReqVO extends PageParam { + + @Schema(description = "批次 UUID", example = "550e8400-e29b-41d4-a716-446655440000") + private String uuid; + + @Schema(description = "SN 码", example = "SN20260305000001") + private String code; + + @Schema(description = "物料编号", example = "1") + private Long itemId; + + @Schema(description = "批次号", example = "BATCH001") + private String batchCode; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnRespVO.java new file mode 100644 index 0000000000..f42011180b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/vo/MesWmSnRespVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES SN 码 Response VO") +@Data +@Accessors(chain = true) +public class MesWmSnRespVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "批次 UUID", example = "550e8400-e29b-41d4-a716-446655440000") + private String uuid; + + @Schema(description = "SN 码", example = "SN20260305000001") + @ExcelProperty("SN 码") + private String code; + + @Schema(description = "物料编号", example = "1") + private Long itemId; + + @Schema(description = "物料编码", example = "ITEM001") + @ExcelProperty("物料编码") + private String itemCode; + + @Schema(description = "物料名称", example = "物料A") + @ExcelProperty("物料名称") + private String itemName; + + @Schema(description = "规格型号", example = "100*200") + @ExcelProperty("规格型号") + private String specification; + + @Schema(description = "批次号", example = "BATCH001") + @ExcelProperty("批次号") + private String batchCode; + + @Schema(description = "生产工单编号", example = "1") + private Long workOrderId; + + @Schema(description = "创建时间") + @ExcelProperty("生成时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/sn/MesWmSnDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/sn/MesWmSnDO.java new file mode 100644 index 0000000000..bb1fa981dd --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/sn/MesWmSnDO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * MES SN 码 DO + * + * @author 芋道源码 + */ +@TableName("mes_wm_sn") +@KeySequence("mes_wm_sn_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmSnDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 批次 UUID(用于标记同一批次生成的 SN 码) + */ + private String uuid; + /** + * SN 码(唯一) + */ + private String code; + /** + * 物料编号 + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 批次号 + */ + private String batchCode; + // TODO @芋艿:【暂时不处理】看看后续要不要去掉这个字段。 + /** + * 生产工单编号 + * + * 关联 {@link MesProWorkOrderDO#getId()} + */ + private Long workOrderId; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/sn/MesWmSnMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/sn/MesWmSnMapper.java new file mode 100644 index 0000000000..6eb41e81d9 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/sn/MesWmSnMapper.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.sn; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES SN 码 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesWmSnMapper extends BaseMapperX { + + /** + * 按 UUID 分组查询 SN 码分页(聚合查询) + */ + default PageResult selectPageGroupByUuid(MesWmSnPageReqVO reqVO) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + query.eqIfPresent(MesWmSnDO::getUuid, reqVO.getUuid()) + .likeIfPresent(MesWmSnDO::getCode, reqVO.getCode()) + .eqIfPresent(MesWmSnDO::getItemId, reqVO.getItemId()) + .likeIfPresent(MesWmSnDO::getBatchCode, reqVO.getBatchCode()) + .betweenIfPresent(MesWmSnDO::getCreateTime, reqVO.getCreateTime()); + query.selectAs(MesWmSnDO::getUuid, MesWmSnGroupRespVO::getUuid) + .selectMax(MesWmSnDO::getItemId, MesWmSnGroupRespVO::getItemId) + .selectMax(MesWmSnDO::getBatchCode, MesWmSnGroupRespVO::getBatchCode) + .selectMax(MesWmSnDO::getWorkOrderId, MesWmSnGroupRespVO::getWorkOrderId) + .selectMax(MesWmSnDO::getCreateTime, MesWmSnGroupRespVO::getCreateTime) + .selectAs("COUNT(*)", MesWmSnGroupRespVO::getCount) + .groupBy(MesWmSnDO::getUuid) + .last("ORDER BY MAX(t.create_time) DESC"); // 避免 this is incompatible with sql_mode=only_full_group_by 报错 + return selectJoinPage(reqVO, MesWmSnGroupRespVO.class, query); + } + + default List selectListByUuid(String uuid) { + return selectList(new LambdaQueryWrapperX() + .eq(MesWmSnDO::getUuid, uuid) + .orderByAsc(MesWmSnDO::getId)); + } + + default int deleteByUuid(String uuid) { + return delete(new LambdaQueryWrapperX() + .eq(MesWmSnDO::getUuid, uuid)); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java new file mode 100644 index 0000000000..043376ae02 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.mes.enums.md.autocode; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * MES 编码规则代码枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesMdAutoCodeRuleCodeEnum { + + SN_CODE("SN_CODE", "SN 码"); + + /** + * 规则代码 + */ + private final String code; + /** + * 规则名称 + */ + private final String name; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordService.java index 41b8012306..13edef4538 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordService.java @@ -7,6 +7,16 @@ package cn.iocoder.yudao.module.mes.service.md.autocode; */ public interface MesMdAutoCodeRecordService { + /** + * 生成编码(无输入字符) + * + * @param ruleCode 规则编码 + * @return 生成的编码 + */ + default String generateAutoCode(String ruleCode) { + return generateAutoCode(ruleCode, null); + } + /** * 生成编码 * diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnService.java new file mode 100644 index 0000000000..15e29d129b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnService.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.mes.service.wm.sn; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; + +import java.util.List; + +/** + * MES SN 码 Service 接口 + * + * @author 芋道源码 + */ +public interface MesWmSnService { + + /** + * 批量生成 SN 码 + * + * @param reqVO 生成请求 + */ + void generateSnCodes(MesWmSnGenerateReqVO reqVO); + + /** + * 获得 SN 码分组分页(按 UUID 聚合) + * + * @param reqVO 分页查询 + * @return SN 码分组分页 + */ + PageResult getSnGroupPage(MesWmSnPageReqVO reqVO); + + /** + * 获得批次 SN 码列表 + * + * @param uuid 批次 UUID + * @return SN 码列表 + */ + List getSnListByUuid(String uuid); + + /** + * 批量删除 SN 码(按批次 UUID) + * + * @param uuid 批次 UUID + */ + void deleteSnByUuid(String uuid); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java new file mode 100644 index 0000000000..283e9001f4 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.mes.service.wm.sn; + +import cn.hutool.core.util.IdUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.sn.MesWmSnMapper; +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; +import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * MES SN 码 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class MesWmSnServiceImpl implements MesWmSnService { + + @Resource + private MesWmSnMapper snMapper; + @Resource + private MesMdAutoCodeRecordService autoCodeRecordService; + + @Override + @Transactional(rollbackFor = Exception.class) + public void generateSnCodes(MesWmSnGenerateReqVO reqVO) { + List sns = new ArrayList<>(reqVO.getCount()); + // 生成批次 UUID + String uuid = IdUtil.fastSimpleUUID(); + // 批量生成 SN 码 + for (int i = 0; i < reqVO.getCount(); i++) { + String snCode = autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.SN_CODE.getCode()); + sns.add(new MesWmSnDO().setUuid(uuid).setCode(snCode) + .setItemId(reqVO.getItemId()).setBatchCode(reqVO.getBatchCode()) + .setWorkOrderId(reqVO.getWorkOrderId())); + } + // 批量插入 + snMapper.insertBatch(sns); + } + + @Override + public PageResult getSnGroupPage(MesWmSnPageReqVO reqVO) { + return snMapper.selectPageGroupByUuid(reqVO); + } + + @Override + public List getSnListByUuid(String uuid) { + return snMapper.selectListByUuid(uuid); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteSnByUuid(String uuid) { + snMapper.deleteByUuid(uuid); + } + +} diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/sn/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/sn/index.ts new file mode 100644 index 0000000000..c2b67fb03b --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/sn/index.ts @@ -0,0 +1,45 @@ +import request from '@/config/axios' + +// MES SN 码 VO +export interface WmSnVO { + id: number + snCode: string + itemId: number + itemCode: string + itemName: string + specification: string + batchCode: string + workOrderId: number + createTime: string +} + +// MES SN 码生成 VO +export interface WmSnGenerateVO { + itemId: number + batchCode?: string + workOrderId?: number + snNum: number +} + +// MES SN 码 API +export const WmSnApi = { + // 生成 SN 码 + generateSnCodes: async (data: WmSnGenerateVO) => { + return await request.post({ url: '/mes/wm/sn/generate', data }) + }, + + // 查询 SN 码分页 + getSnPage: async (params: any) => { + return await request.get({ url: '/mes/wm/sn/page', params }) + }, + + // 批量删除 SN 码 + deleteSnBatch: async (ids: string) => { + return await request.delete({ url: '/mes/wm/sn/delete-batch', params: { ids } }) + }, + + // 导出 SN 码 Excel + exportSnExcel: async (params: any) => { + return await request.download({ url: '/mes/wm/sn/export-excel', params }) + } +} diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/mes/wm/sn/index.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/mes/wm/sn/index.vue new file mode 100644 index 0000000000..ba0e73ae39 --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/mes/wm/sn/index.vue @@ -0,0 +1,248 @@ + + +