Commit 6f4aa8fd66cb63dd9973e0c408f45f6a24c56daa

Authored by YunaiV
1 parent b50ca061

✨ feat(mes): 添加 MES 领料出库单相关数据模型及接口

新增 MES 领料出库单及其行的响应和请求 VO,包含必要的字段和注释。
同时实现了相关的控制器和服务接口,支持创建、更新、删除和查询领料出库单的功能。

此功能将提升领料出库单的管理效率,便于后续的业务逻辑实现。
Showing 19 changed files with 1218 additions and 0 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  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.wm.productionissue.vo.MesWmProductionIssuePageReqVO;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueRespVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO;
  13 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueLineRespVO;
  14 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO;
  15 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
  16 +import cn.iocoder.yudao.module.mes.service.wm.productionissue.MesWmProductionIssueService;
  17 +import cn.iocoder.yudao.module.mes.service.wm.productionissue.MesWmProductionIssueLineService;
  18 +import io.swagger.v3.oas.annotations.Operation;
  19 +import io.swagger.v3.oas.annotations.Parameter;
  20 +import io.swagger.v3.oas.annotations.tags.Tag;
  21 +import jakarta.annotation.Resource;
  22 +import jakarta.servlet.http.HttpServletResponse;
  23 +import jakarta.validation.Valid;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
  25 +import org.springframework.validation.annotation.Validated;
  26 +import org.springframework.web.bind.annotation.*;
  27 +
  28 +import java.io.IOException;
  29 +import java.util.Collections;
  30 +import java.util.List;
  31 +import java.util.Map;
  32 +
  33 +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
  34 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  36 +
  37 +@Tag(name = "管理后台 - MES 领料出库单")
  38 +@RestController
  39 +@RequestMapping("/mes/wm/production-issue")
  40 +@Validated
  41 +public class MesWmProductionIssueController {
  42 +
  43 + @Resource
  44 + private MesWmProductionIssueService issueService;
  45 + @Resource
  46 + private MesWmProductionIssueLineService issueLineService;
  47 +
  48 + @PostMapping("/create")
  49 + @Operation(summary = "创建领料出库单")
  50 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:create')")
  51 + public CommonResult<Long> createIssue(@Valid @RequestBody MesWmProductionIssueSaveReqVO createReqVO) {
  52 + return success(issueService.createIssue(createReqVO));
  53 + }
  54 +
  55 + @PutMapping("/update")
  56 + @Operation(summary = "修改领料出库单")
  57 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')")
  58 + public CommonResult<Boolean> updateIssue(@Valid @RequestBody MesWmProductionIssueSaveReqVO updateReqVO) {
  59 + issueService.updateIssue(updateReqVO);
  60 + return success(true);
  61 + }
  62 +
  63 + @DeleteMapping("/delete")
  64 + @Operation(summary = "删除领料出库单")
  65 + @Parameter(name = "id", description = "编号", required = true)
  66 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:delete')")
  67 + public CommonResult<Boolean> deleteIssue(@RequestParam("id") Long id) {
  68 + issueService.deleteIssue(id);
  69 + return success(true);
  70 + }
  71 +
  72 + @GetMapping("/get")
  73 + @Operation(summary = "获得领料出库单")
  74 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  75 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:query')")
  76 + public CommonResult<MesWmProductionIssueRespVO> getIssue(@RequestParam("id") Long id) {
  77 + MesWmProductionIssueDO issueHeader = issueService.getIssue(id);
  78 + if (issueHeader == null) {
  79 + return success(null);
  80 + }
  81 + return success(buildRespVOList(Collections.singletonList(issueHeader)).get(0));
  82 + }
  83 +
  84 + @GetMapping("/page")
  85 + @Operation(summary = "获得领料出库单分页")
  86 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:query')")
  87 + public CommonResult<PageResult<MesWmProductionIssueRespVO>> getIssuePage(
  88 + @Valid MesWmProductionIssuePageReqVO pageReqVO) {
  89 + PageResult<MesWmProductionIssueDO> pageResult = issueService.getIssuePage(pageReqVO);
  90 + return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal()));
  91 + }
  92 +
  93 + @GetMapping("/export-excel")
  94 + @Operation(summary = "导出领料出库单 Excel")
  95 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:export')")
  96 + @ApiAccessLog(operateType = EXPORT)
  97 + public void exportIssueExcel(@Valid MesWmProductionIssuePageReqVO pageReqVO,
  98 + HttpServletResponse response) throws IOException {
  99 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  100 + PageResult<MesWmProductionIssueDO> pageResult = issueService.getIssuePage(pageReqVO);
  101 + ExcelUtils.write(response, "领料出库单.xls", "数据", MesWmProductionIssueRespVO.class,
  102 + buildRespVOList(pageResult.getList()));
  103 + }
  104 +
  105 + @PutMapping("/approve")
  106 + @Operation(summary = "审批领料出库单")
  107 + @Parameter(name = "id", description = "编号", required = true)
  108 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')")
  109 + public CommonResult<Boolean> approveIssue(@RequestParam("id") Long id) {
  110 + issueService.approveIssue(id);
  111 + return success(true);
  112 + }
  113 +
  114 + @PutMapping("/unapprove")
  115 + @Operation(summary = "反审批领料出库单")
  116 + @Parameter(name = "id", description = "编号", required = true)
  117 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')")
  118 + public CommonResult<Boolean> unapproveIssue(@RequestParam("id") Long id) {
  119 + issueService.unapproveIssue(id);
  120 + return success(true);
  121 + }
  122 +
  123 + @PutMapping("/finish")
  124 + @Operation(summary = "完成领料出库单")
  125 + @Parameter(name = "id", description = "编号", required = true)
  126 + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')")
  127 + public CommonResult<Boolean> finishIssue(@RequestParam("id") Long id) {
  128 + issueService.finishIssue(id);
  129 + return success(true);
  130 + }
  131 +
  132 + // ==================== 拼接 VO ====================
  133 +
  134 + private List<MesWmProductionIssueRespVO> buildRespVOList(List<MesWmProductionIssueDO> list) {
  135 + if (CollUtil.isEmpty(list)) {
  136 + return Collections.emptyList();
  137 + }
  138 +
  139 + // 1. 转换基础 VO
  140 + List<MesWmProductionIssueRespVO> respVOList = BeanUtils.toBean(list, MesWmProductionIssueRespVO.class);
  141 +
  142 + // 2. 查询行数据
  143 + Map<Long, List<MesWmProductionIssueLineDO>> lineMap = issueLineService.getIssueLineListByIssueIds(
  144 + convertSet(list, MesWmProductionIssueDO::getId))
  145 + .stream()
  146 + .collect(java.util.stream.Collectors.groupingBy(MesWmProductionIssueLineDO::getIssueId));
  147 +
  148 + // 3. 填充行数据
  149 + respVOList.forEach(respVO -> {
  150 + List<MesWmProductionIssueLineDO> lines = lineMap.get(respVO.getId());
  151 + if (CollUtil.isNotEmpty(lines)) {
  152 + respVO.setLines(BeanUtils.toBean(lines, MesWmProductionIssueLineRespVO.class));
  153 + }
  154 + });
  155 +
  156 + // TODO @AI:关联查询工作站、工单、任务、客户等数据,填充到响应 VO 中
  157 +
  158 + return respVOList;
  159 + }
  160 +
  161 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueLineRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - MES 领料出库单行 Response VO")
  10 +@Data
  11 +public class MesWmProductionIssueLineRespVO {
  12 +
  13 + @Schema(description = "行ID", example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "领料单ID", example = "1")
  17 + private Long issueId;
  18 +
  19 + @Schema(description = "物料ID", example = "1")
  20 + private Long itemId;
  21 +
  22 + @Schema(description = "领料数量", example = "100.00")
  23 + private BigDecimal quantityIssued;
  24 +
  25 + @Schema(description = "批次ID", example = "1")
  26 + private Long batchId;
  27 +
  28 + @Schema(description = "备注", example = "备注")
  29 + private String remark;
  30 +
  31 + @Schema(description = "创建时间")
  32 + private LocalDateTime createTime;
  33 +
  34 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueLineSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - MES 领料出库单行 Save Request VO")
  9 +@Data
  10 +public class MesWmProductionIssueLineSaveReqVO {
  11 +
  12 + @Schema(description = "行ID", example = "1")
  13 + private Long id;
  14 +
  15 + @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + private Long itemId;
  17 +
  18 + @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  19 + private BigDecimal quantityIssued;
  20 +
  21 + @Schema(description = "批次ID", example = "1")
  22 + private Long batchId;
  23 +
  24 + @Schema(description = "备注", example = "备注")
  25 + private String remark;
  26 +
  27 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo;
  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 org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@Schema(description = "管理后台 - MES 领料出库单分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +public class MesWmProductionIssuePageReqVO extends PageParam {
  17 +
  18 + @Schema(description = "领料单编号", example = "ISSUE20250226001")
  19 + private String code;
  20 +
  21 + @Schema(description = "领料单名称", example = "生产领料")
  22 + private String name;
  23 +
  24 + @Schema(description = "工作站ID", example = "1")
  25 + private Long workstationId;
  26 +
  27 + @Schema(description = "生产工单ID", example = "1")
  28 + private Long workorderId;
  29 +
  30 + @Schema(description = "生产任务ID", example = "1")
  31 + private Long taskId;
  32 +
  33 + @Schema(description = "客户ID", example = "1")
  34 + private Long clientId;
  35 +
  36 + @Schema(description = "状态", example = "10")
  37 + private Integer status;
  38 +
  39 + @Schema(description = "领料日期范围")
  40 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  41 + private LocalDateTime[] issueDate;
  42 +
  43 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - MES 领料出库单 Response VO")
  10 +@Data
  11 +public class MesWmProductionIssueRespVO {
  12 +
  13 + @Schema(description = "编号", example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "领料单编号", example = "ISSUE20250226001")
  17 + private String code;
  18 +
  19 + @Schema(description = "领料单名称", example = "生产领料")
  20 + private String name;
  21 +
  22 + @Schema(description = "工作站ID", example = "1")
  23 + private Long workstationId;
  24 +
  25 + @Schema(description = "生产工单ID", example = "1")
  26 + private Long workorderId;
  27 +
  28 + @Schema(description = "生产任务ID", example = "1")
  29 + private Long taskId;
  30 +
  31 + @Schema(description = "客户ID", example = "1")
  32 + private Long clientId;
  33 +
  34 + @Schema(description = "领料日期")
  35 + private LocalDateTime issueDate;
  36 +
  37 + @Schema(description = "需求时间")
  38 + private LocalDateTime requiredTime;
  39 +
  40 + @Schema(description = "状态", example = "10")
  41 + private Integer status;
  42 +
  43 + @Schema(description = "备注", example = "备注")
  44 + private String remark;
  45 +
  46 + @Schema(description = "创建时间")
  47 + private LocalDateTime createTime;
  48 +
  49 + @Schema(description = "领料单行列表")
  50 + private List<MesWmProductionIssueLineRespVO> lines;
  51 +
  52 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - MES 领料出库单新增/修改 Request VO")
  10 +@Data
  11 +public class MesWmProductionIssueSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "领料单编号", example = "ISSUE20250226001")
  17 + private String code;
  18 +
  19 + @Schema(description = "领料单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "生产领料")
  20 + private String name;
  21 +
  22 + @Schema(description = "工作站ID", example = "1")
  23 + private Long workstationId;
  24 +
  25 + @Schema(description = "生产工单ID", example = "1")
  26 + private Long workorderId;
  27 +
  28 + @Schema(description = "生产任务ID", example = "1")
  29 + private Long taskId;
  30 +
  31 + @Schema(description = "客户ID", example = "1")
  32 + private Long clientId;
  33 +
  34 + @Schema(description = "领料日期")
  35 + private LocalDateTime issueDate;
  36 +
  37 + @Schema(description = "需求时间")
  38 + private LocalDateTime requiredTime;
  39 +
  40 + @Schema(description = "备注", example = "备注")
  41 + private String remark;
  42 +
  43 + @Schema(description = "预留字段1")
  44 + private String attribute1;
  45 +
  46 + @Schema(description = "预留字段2")
  47 + private String attribute2;
  48 +
  49 + @Schema(description = "预留字段3")
  50 + private Integer attribute3;
  51 +
  52 + @Schema(description = "预留字段4")
  53 + private Integer attribute4;
  54 +
  55 + @Schema(description = "领料单行列表")
  56 + private List<MesWmProductionIssueLineSaveReqVO> lines;
  57 +
  58 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
  8 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum;
  9 +import com.baomidou.mybatisplus.annotation.KeySequence;
  10 +import com.baomidou.mybatisplus.annotation.TableId;
  11 +import com.baomidou.mybatisplus.annotation.TableName;
  12 +import lombok.*;
  13 +
  14 +import java.time.LocalDateTime;
  15 +
  16 +// TODO @AI:【需要一起讨论】不要直接改;是不是叫 issueheader 包?主要后续别的表也有 issue,希望区分下;还是加个合理的前缀?就像 wm_outsource_issue 这种;
  17 +/**
  18 + * MES 领料出库单 DO
  19 + */
  20 +@TableName("mes_wm_issue_header")
  21 +@KeySequence("mes_wm_issue_header_seq")
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = true)
  24 +@ToString(callSuper = true)
  25 +@Builder
  26 +@NoArgsConstructor
  27 +@AllArgsConstructor
  28 +public class MesWmProductionIssueDO extends BaseDO {
  29 +
  30 + /**
  31 + * 编号
  32 + */
  33 + @TableId
  34 + private Long id;
  35 + /**
  36 + * 领料单编号
  37 + */
  38 + private String code;
  39 + /**
  40 + * 领料单名称
  41 + */
  42 + private String name;
  43 + /**
  44 + * 工作站 ID
  45 + *
  46 + * 关联 {@link MesMdWorkstationDO#getId()}
  47 + */
  48 + private Long workstationId;
  49 + // TODO @AI:workOrderId;
  50 + /**
  51 + * 生产工单 ID
  52 + *
  53 + * 关联 {@link MesProWorkOrderDO#getId()}
  54 + */
  55 + private Long workorderId;
  56 + // TODO @芋艿:【疑问】这个字段的来源?
  57 + /**
  58 + * 生产任务 ID
  59 + *
  60 + * 关联 {@link MesProTaskDO#getId()}
  61 + */
  62 + private Long taskId;
  63 + // TODO @AI:应该不用记录?因为 workorderId 字段的;
  64 + /**
  65 + * 客户 ID
  66 + *
  67 + * 关联 {@link MesMdClientDO#getId()}
  68 + */
  69 + private Long clientId;
  70 + // TODO @芋艿:【疑问】这个字段的更新时间;
  71 + /**
  72 + * 领料日期
  73 + */
  74 + private LocalDateTime issueDate;
  75 + /**
  76 + * 需求时间
  77 + */
  78 + private LocalDateTime requiredTime;
  79 + /**
  80 + * 状态
  81 + *
  82 + * 枚举 {@link MesWmProductionIssueStatusEnum}
  83 + */
  84 + private Integer status;
  85 + /**
  86 + * 备注
  87 + */
  88 + private String remark;
  89 + /**
  90 + * 预留字段 1
  91 + */
  92 + private String attribute1;
  93 + /**
  94 + * 预留字段 2
  95 + */
  96 + private String attribute2;
  97 + /**
  98 + * 预留字段 3
  99 + */
  100 + private Integer attribute3;
  101 + /**
  102 + * 预留字段 4
  103 + */
  104 + private Integer attribute4;
  105 +
  106 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
  9 +import com.baomidou.mybatisplus.annotation.KeySequence;
  10 +import com.baomidou.mybatisplus.annotation.TableId;
  11 +import com.baomidou.mybatisplus.annotation.TableName;
  12 +import lombok.*;
  13 +
  14 +import java.math.BigDecimal;
  15 +
  16 +/**
  17 + * MES 领料出库明细 DO
  18 + */
  19 +@TableName("mes_wm_issue_detail")
  20 +@KeySequence("mes_wm_issue_detail_seq")
  21 +@Data
  22 +@EqualsAndHashCode(callSuper = true)
  23 +@ToString(callSuper = true)
  24 +@Builder
  25 +@NoArgsConstructor
  26 +@AllArgsConstructor
  27 +public class MesWmProductionIssueDetailDO extends BaseDO {
  28 +
  29 + /**
  30 + * 编号
  31 + */
  32 + @TableId
  33 + private Long id;
  34 + /**
  35 + * 领料单ID
  36 + *
  37 + * 关联 {@link MesWmProductionIssueDO#getId()}
  38 + */
  39 + private Long issueId;
  40 + /**
  41 + * 行ID
  42 + *
  43 + * 关联 {@link MesWmProductionIssueLineDO#getId()}
  44 + */
  45 + private Long lineId;
  46 + /**
  47 + * 库存记录ID
  48 + *
  49 + * 关联 {@link MesWmMaterialStockDO#getId()}
  50 + */
  51 + private Long materialStockId;
  52 + /**
  53 + * 物料ID
  54 + *
  55 + * 关联 {@link MesMdItemDO#getId()}
  56 + */
  57 + private Long itemId;
  58 + /**
  59 + * 领料数量
  60 + */
  61 + private BigDecimal quantity;
  62 + /**
  63 + * 批次ID
  64 + */
  65 + private Long batchId;
  66 + /**
  67 + * 仓库ID
  68 + *
  69 + * 关联 {@link MesWmWarehouseDO#getId()}
  70 + */
  71 + private Long warehouseId;
  72 + /**
  73 + * 库区ID
  74 + *
  75 + * 关联 {@link MesWmWarehouseLocationDO#getId()}
  76 + */
  77 + private Long locationId;
  78 + /**
  79 + * 库位ID
  80 + *
  81 + * 关联 {@link MesWmWarehouseAreaDO#getId()}
  82 + */
  83 + private Long areaId;
  84 + /**
  85 + * 备注
  86 + */
  87 + private String remark;
  88 + /**
  89 + * 预留字段1
  90 + */
  91 + private String attribute1;
  92 + /**
  93 + * 预留字段2
  94 + */
  95 + private String attribute2;
  96 + /**
  97 + * 预留字段3
  98 + */
  99 + private Integer attribute3;
  100 + /**
  101 + * 预留字段4
  102 + */
  103 + private Integer attribute4;
  104 +
  105 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  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 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * MES 领料出库单行 DO
  14 + */
  15 +@TableName("mes_wm_issue_line")
  16 +@KeySequence("mes_wm_issue_line_seq")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class MesWmProductionIssueLineDO extends BaseDO {
  24 +
  25 + /**
  26 + * 编号
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 领料单 ID
  32 + *
  33 + * 关联 {@link MesWmProductionIssueDO#getId()}
  34 + */
  35 + private Long issueId;
  36 + /**
  37 + * 物料 ID
  38 + *
  39 + * 关联 {@link MesMdItemDO#getId()}
  40 + */
  41 + private Long itemId;
  42 + // TODO @AI:是不是精简成 quantity?
  43 + /**
  44 + * 领料数量
  45 + */
  46 + private BigDecimal quantityIssued;
  47 + /**
  48 + * 批次 ID
  49 + */
  50 + private Long batchId;
  51 + /**
  52 + * 备注
  53 + */
  54 + private String remark;
  55 + /**
  56 + * 预留字段 1
  57 + */
  58 + private String attribute1;
  59 + /**
  60 + * 预留字段 2
  61 + */
  62 + private String attribute2;
  63 + /**
  64 + * 预留字段 3
  65 + */
  66 + private Integer attribute3;
  67 + /**
  68 + * 预留字段 4
  69 + */
  70 + private Integer attribute4;
  71 +
  72 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 领料出库明细 Mapper
  12 + */
  13 +@Mapper
  14 +public interface MesWmProductionIssueDetailMapper extends BaseMapperX<MesWmProductionIssueDetailDO> {
  15 +
  16 + default List<MesWmProductionIssueDetailDO> selectListByIssueId(Long issueId) {
  17 + return selectList(MesWmProductionIssueDetailDO::getIssueId, issueId);
  18 + }
  19 +
  20 + default List<MesWmProductionIssueDetailDO> selectListByIssueIds(Collection<Long> issueIds) {
  21 + return selectList(MesWmProductionIssueDetailDO::getIssueId, issueIds);
  22 + }
  23 +
  24 + default List<MesWmProductionIssueDetailDO> selectListByLineId(Long lineId) {
  25 + return selectList(MesWmProductionIssueDetailDO::getLineId, lineId);
  26 + }
  27 +
  28 + default void deleteByIssueId(Long issueId) {
  29 + delete(MesWmProductionIssueDetailDO::getIssueId, issueId);
  30 + }
  31 +
  32 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueLineMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 领料出库单行 Mapper
  12 + */
  13 +@Mapper
  14 +public interface MesWmProductionIssueLineMapper extends BaseMapperX<MesWmProductionIssueLineDO> {
  15 +
  16 + default List<MesWmProductionIssueLineDO> selectListByIssueId(Long issueId) {
  17 + return selectList(MesWmProductionIssueLineDO::getIssueId, issueId);
  18 + }
  19 +
  20 + default List<MesWmProductionIssueLineDO> selectListByIssueIds(Collection<Long> issueIds) {
  21 + return selectList(MesWmProductionIssueLineDO::getIssueId, issueIds);
  22 + }
  23 +
  24 + default void deleteByIssueId(Long issueId) {
  25 + delete(MesWmProductionIssueLineDO::getIssueId, issueId);
  26 + }
  27 +
  28 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue;
  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.wm.productionissue.vo.MesWmProductionIssuePageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * MES 领料出库单 Mapper
  12 + */
  13 +@Mapper
  14 +public interface MesWmProductionIssueMapper extends BaseMapperX<MesWmProductionIssueDO> {
  15 +
  16 + default PageResult<MesWmProductionIssueDO> selectPage(MesWmProductionIssuePageReqVO reqVO) {
  17 + return selectPage(reqVO, new LambdaQueryWrapperX<MesWmProductionIssueDO>()
  18 + .likeIfPresent(MesWmProductionIssueDO::getCode, reqVO.getCode())
  19 + .likeIfPresent(MesWmProductionIssueDO::getName, reqVO.getName())
  20 + .eqIfPresent(MesWmProductionIssueDO::getWorkstationId, reqVO.getWorkstationId())
  21 + .eqIfPresent(MesWmProductionIssueDO::getWorkorderId, reqVO.getWorkorderId())
  22 + .eqIfPresent(MesWmProductionIssueDO::getTaskId, reqVO.getTaskId())
  23 + .eqIfPresent(MesWmProductionIssueDO::getClientId, reqVO.getClientId())
  24 + .eqIfPresent(MesWmProductionIssueDO::getStatus, reqVO.getStatus())
  25 + .betweenIfPresent(MesWmProductionIssueDO::getIssueDate, reqVO.getIssueDate())
  26 + .orderByDesc(MesWmProductionIssueDO::getId));
  27 + }
  28 +
  29 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductionIssueStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.wm;
  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 +// TODO @AI:需要使用 status constants 去映射;
  10 +/**
  11 + * MES 领料出库单状态枚举
  12 + */
  13 +@Getter
  14 +@AllArgsConstructor
  15 +public enum MesWmProductionIssueStatusEnum implements ArrayValuable<Integer> {
  16 +
  17 + PREPARE(10, "准备中"),
  18 + APPROVED(20, "已审批"),
  19 + FINISHED(30, "已完成");
  20 +
  21 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductionIssueStatusEnum::getStatus).toArray(Integer[]::new);
  22 +
  23 + /**
  24 + * 状态
  25 + */
  26 + private final Integer status;
  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/service/wm/productionissue/MesWmProductionIssueDetailService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * MES 领料出库明细 Service 接口
  10 + */
  11 +public interface MesWmProductionIssueDetailService {
  12 +
  13 + /**
  14 + * 根据领料单ID获取明细列表
  15 + *
  16 + * @param issueId 领料单ID
  17 + * @return 明细列表
  18 + */
  19 + List<MesWmProductionIssueDetailDO> getIssueDetailListByIssueId(Long issueId);
  20 +
  21 + /**
  22 + * 根据领料单ID集合获取明细列表
  23 + *
  24 + * @param issueIds 领料单ID集合
  25 + * @return 明细列表
  26 + */
  27 + List<MesWmProductionIssueDetailDO> getIssueDetailListByIssueIds(Collection<Long> issueIds);
  28 +
  29 + /**
  30 + * 根据行ID获取明细列表
  31 + *
  32 + * @param lineId 行ID
  33 + * @return 明细列表
  34 + */
  35 + List<MesWmProductionIssueDetailDO> getIssueDetailListByLineId(Long lineId);
  36 +
  37 + /**
  38 + * 根据领料单ID删除明细
  39 + *
  40 + * @param issueId 领料单ID
  41 + */
  42 + void deleteIssueDetailByIssueId(Long issueId);
  43 +
  44 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO;
  4 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueDetailMapper;
  5 +import jakarta.annotation.Resource;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 领料出库明细 Service 实现类
  14 + */
  15 +@Service
  16 +@Validated
  17 +public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIssueDetailService {
  18 +
  19 + @Resource
  20 + private MesWmProductionIssueDetailMapper issueDetailMapper;
  21 +
  22 + @Override
  23 + public List<MesWmProductionIssueDetailDO> getIssueDetailListByIssueId(Long issueId) {
  24 + return issueDetailMapper.selectListByIssueId(issueId);
  25 + }
  26 +
  27 + @Override
  28 + public List<MesWmProductionIssueDetailDO> getIssueDetailListByIssueIds(Collection<Long> issueIds) {
  29 + return issueDetailMapper.selectListByIssueIds(issueIds);
  30 + }
  31 +
  32 + @Override
  33 + public List<MesWmProductionIssueDetailDO> getIssueDetailListByLineId(Long lineId) {
  34 + return issueDetailMapper.selectListByLineId(lineId);
  35 + }
  36 +
  37 + @Override
  38 + public void deleteIssueDetailByIssueId(Long issueId) {
  39 + issueDetailMapper.deleteByIssueId(issueId);
  40 + }
  41 +
  42 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * MES 领料出库单行 Service 接口
  10 + */
  11 +public interface MesWmProductionIssueLineService {
  12 +
  13 + /**
  14 + * 根据领料单ID获取行列表
  15 + *
  16 + * @param issueId 领料单ID
  17 + * @return 行列表
  18 + */
  19 + List<MesWmProductionIssueLineDO> getIssueLineListByIssueId(Long issueId);
  20 +
  21 + /**
  22 + * 根据领料单ID集合获取行列表
  23 + *
  24 + * @param issueIds 领料单ID集合
  25 + * @return 行列表
  26 + */
  27 + List<MesWmProductionIssueLineDO> getIssueLineListByIssueIds(Collection<Long> issueIds);
  28 +
  29 + /**
  30 + * 根据领料单ID删除行
  31 + *
  32 + * @param issueId 领料单ID
  33 + */
  34 + void deleteIssueLineByIssueId(Long issueId);
  35 +
  36 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
  4 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper;
  5 +import jakarta.annotation.Resource;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 领料出库单行 Service 实现类
  14 + */
  15 +@Service
  16 +@Validated
  17 +public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssueLineService {
  18 +
  19 + @Resource
  20 + private MesWmProductionIssueLineMapper issueLineMapper;
  21 +
  22 + @Override
  23 + public List<MesWmProductionIssueLineDO> getIssueLineListByIssueId(Long issueId) {
  24 + return issueLineMapper.selectListByIssueId(issueId);
  25 + }
  26 +
  27 + @Override
  28 + public List<MesWmProductionIssueLineDO> getIssueLineListByIssueIds(Collection<Long> issueIds) {
  29 + return issueLineMapper.selectListByIssueIds(issueIds);
  30 + }
  31 +
  32 + @Override
  33 + public void deleteIssueLineByIssueId(Long issueId) {
  34 + issueLineMapper.deleteByIssueId(issueId);
  35 + }
  36 +
  37 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 领料出库单 Service 接口
  14 + */
  15 +public interface MesWmProductionIssueService {
  16 +
  17 + /**
  18 + * 创建领料出库单
  19 + *
  20 + * @param createReqVO 创建信息
  21 + * @return 编号
  22 + */
  23 + Long createIssue(@Valid MesWmProductionIssueSaveReqVO createReqVO);
  24 +
  25 + /**
  26 + * 修改领料出库单
  27 + *
  28 + * @param updateReqVO 修改信息
  29 + */
  30 + void updateIssue(@Valid MesWmProductionIssueSaveReqVO updateReqVO);
  31 +
  32 + /**
  33 + * 删除领料出库单(级联删除行和明细,仅准备中状态允许)
  34 + *
  35 + * @param id 编号
  36 + */
  37 + void deleteIssue(Long id);
  38 +
  39 + /**
  40 + * 获得领料出库单
  41 + *
  42 + * @param id 编号
  43 + * @return 领料出库单
  44 + */
  45 + MesWmProductionIssueDO getIssue(Long id);
  46 +
  47 + /**
  48 + * 获得领料出库单分页
  49 + *
  50 + * @param pageReqVO 分页参数
  51 + * @return 领料出库单分页
  52 + */
  53 + PageResult<MesWmProductionIssueDO> getIssuePage(MesWmProductionIssuePageReqVO pageReqVO);
  54 +
  55 + /**
  56 + * 审批领料出库单(准备中 → 已审批,扣减库存)
  57 + *
  58 + * @param id 编号
  59 + */
  60 + void approveIssue(Long id);
  61 +
  62 + /**
  63 + * 反审批领料出库单(已审批 → 准备中,恢复库存)
  64 + *
  65 + * @param id 编号
  66 + */
  67 + void unapproveIssue(Long id);
  68 +
  69 + /**
  70 + * 完成领料出库单(已审批 → 已完成)
  71 + *
  72 + * @param id 编号
  73 + */
  74 + void finishIssue(Long id);
  75 +
  76 + /**
  77 + * 按编号集合获得领料出库单列表
  78 + *
  79 + * @param ids 编号集合
  80 + * @return 领料出库单列表
  81 + */
  82 + List<MesWmProductionIssueDO> getIssueList(Collection<Long> ids);
  83 +
  84 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productionissue;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO;
  8 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO;
  9 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueLineSaveReqVO;
  10 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
  12 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper;
  13 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper;
  14 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum;
  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.Collection;
  21 +import java.util.Collections;
  22 +import java.util.List;
  23 +
  24 +/**
  25 + * MES 领料出库单 Service 实现类
  26 + */
  27 +@Service
  28 +@Validated
  29 +public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueService {
  30 +
  31 + @Resource
  32 + private MesWmProductionIssueMapper issueHeaderMapper;
  33 +
  34 + @Resource
  35 + private MesWmProductionIssueLineMapper issueLineMapper;
  36 +
  37 + @Resource
  38 + private MesWmProductionIssueLineService issueLineService;
  39 +
  40 + @Resource
  41 + private MesWmProductionIssueDetailService issueDetailService;
  42 +
  43 + @Override
  44 + @Transactional(rollbackFor = Exception.class)
  45 + public Long createIssue(MesWmProductionIssueSaveReqVO createReqVO) {
  46 + // TODO @AI:领料出库关联数据校验待完善(仓库、物料、工单、工位等基础数据校验)
  47 +
  48 + // 1. 插入主表
  49 + MesWmProductionIssueDO issueHeader = BeanUtils.toBean(createReqVO, MesWmProductionIssueDO.class);
  50 + issueHeader.setStatus(MesWmProductionIssueStatusEnum.PREPARE.getStatus());
  51 + issueHeaderMapper.insert(issueHeader);
  52 +
  53 + // 2. 插入行表
  54 + if (CollUtil.isNotEmpty(createReqVO.getLines())) {
  55 + for (MesWmProductionIssueLineSaveReqVO lineVO : createReqVO.getLines()) {
  56 + MesWmProductionIssueLineDO line = BeanUtils.toBean(lineVO, MesWmProductionIssueLineDO.class);
  57 + line.setIssueId(issueHeader.getId());
  58 + issueLineMapper.insert(line);
  59 + }
  60 + }
  61 +
  62 + return issueHeader.getId();
  63 + }
  64 +
  65 + @Override
  66 + @Transactional(rollbackFor = Exception.class)
  67 + public void updateIssue(MesWmProductionIssueSaveReqVO updateReqVO) {
  68 + // 1. 校验存在 + 准备中状态
  69 + validateIssueExistsAndPrepare(updateReqVO.getId());
  70 + // TODO @AI:领料出库关联数据校验待完善(仓库、物料、工单、工位等基础数据校验)
  71 +
  72 + // 2. 更新主表
  73 + MesWmProductionIssueDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueDO.class);
  74 + issueHeaderMapper.updateById(updateObj);
  75 +
  76 + // 3. 更新行表:先删除旧数据,再插入新数据
  77 + issueLineMapper.deleteByIssueId(updateReqVO.getId());
  78 + if (CollUtil.isNotEmpty(updateReqVO.getLines())) {
  79 + for (MesWmProductionIssueLineSaveReqVO lineVO : updateReqVO.getLines()) {
  80 + MesWmProductionIssueLineDO line = BeanUtils.toBean(lineVO, MesWmProductionIssueLineDO.class);
  81 + line.setIssueId(updateReqVO.getId());
  82 + issueLineMapper.insert(line);
  83 + }
  84 + }
  85 + }
  86 +
  87 + @Override
  88 + @Transactional(rollbackFor = Exception.class)
  89 + public void deleteIssue(Long id) {
  90 + // 1. 校验存在 + 准备中状态
  91 + validateIssueExistsAndPrepare(id);
  92 +
  93 + // 2.1 级联删除明细
  94 + issueDetailService.deleteIssueDetailByIssueId(id);
  95 + // 2.2 级联删除行
  96 + issueLineService.deleteIssueLineByIssueId(id);
  97 + // 2.3 删除主表
  98 + issueHeaderMapper.deleteById(id);
  99 + }
  100 +
  101 + @Override
  102 + public MesWmProductionIssueDO getIssue(Long id) {
  103 + return issueHeaderMapper.selectById(id);
  104 + }
  105 +
  106 + @Override
  107 + public PageResult<MesWmProductionIssueDO> getIssuePage(MesWmProductionIssuePageReqVO pageReqVO) {
  108 + return issueHeaderMapper.selectPage(pageReqVO);
  109 + }
  110 +
  111 + @Override
  112 + @Transactional(rollbackFor = Exception.class)
  113 + public void approveIssue(Long id) {
  114 + // 1.1 校验存在
  115 + MesWmProductionIssueDO issueHeader = validateIssueExists(id);
  116 + // 1.2 校验状态:只有准备中才允许审批
  117 + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) {
  118 +// throw exception(WM_ISSUE_STATUS_INVALID);
  119 + throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下;
  120 + }
  121 +
  122 + // 2. 准备中 → 已审批
  123 + issueHeaderMapper.updateById(new MesWmProductionIssueDO()
  124 + .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVED.getStatus()));
  125 +
  126 + // TODO @AI:扣减库存逻辑待完善(需要调用库存服务,根据 detail 表扣减库存)
  127 + }
  128 +
  129 + @Override
  130 + @Transactional(rollbackFor = Exception.class)
  131 + public void unapproveIssue(Long id) {
  132 + // 1.1 校验存在
  133 + MesWmProductionIssueDO issueHeader = validateIssueExists(id);
  134 + // 1.2 校验状态:只有已审批才允许反审批
  135 + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issueHeader.getStatus())) {
  136 +// throw exception(WM_ISSUE_STATUS_INVALID);
  137 + throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下;
  138 + }
  139 +
  140 + // 2. 已审批 → 准备中
  141 + issueHeaderMapper.updateById(new MesWmProductionIssueDO()
  142 + .setId(id).setStatus(MesWmProductionIssueStatusEnum.PREPARE.getStatus()));
  143 +
  144 + // TODO @AI:恢复库存逻辑待完善(需要调用库存服务,根据 detail 表恢复库存)
  145 + }
  146 +
  147 + @Override
  148 + public void finishIssue(Long id) {
  149 + // 1.1 校验存在
  150 + MesWmProductionIssueDO issueHeader = validateIssueExists(id);
  151 + // 1.2 校验状态:只有已审批才允许完成
  152 + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issueHeader.getStatus())) {
  153 +// throw exception(WM_ISSUE_STATUS_INVALID);
  154 + throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下;
  155 + }
  156 +
  157 + // 2. 已审批 → 已完成
  158 + issueHeaderMapper.updateById(new MesWmProductionIssueDO()
  159 + .setId(id).setStatus(MesWmProductionIssueStatusEnum.FINISHED.getStatus()));
  160 + }
  161 +
  162 + @Override
  163 + public List<MesWmProductionIssueDO> getIssueList(Collection<Long> ids) {
  164 + if (CollUtil.isEmpty(ids)) {
  165 + return Collections.emptyList();
  166 + }
  167 + return issueHeaderMapper.selectByIds(ids);
  168 + }
  169 +
  170 + private MesWmProductionIssueDO validateIssueExists(Long id) {
  171 + MesWmProductionIssueDO issueHeader = issueHeaderMapper.selectById(id);
  172 + if (issueHeader == null) {
  173 +// throw exception(WM_ISSUE_NOT_EXISTS);
  174 + throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下;
  175 + }
  176 + return issueHeader;
  177 + }
  178 +
  179 + /**
  180 + * 校验领料出库单存在且为准备中状态
  181 + */
  182 + private MesWmProductionIssueDO validateIssueExistsAndPrepare(Long id) {
  183 + MesWmProductionIssueDO issueHeader = validateIssueExists(id);
  184 + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) {
  185 +// throw exception(WM_ISSUE_STATUS_INVALID);
  186 + throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下;
  187 + }
  188 + return issueHeader;
  189 + }
  190 +
  191 +}
... ...