Commit 7c90ad4a76921ea9912ee5fbc0ace5e6edfbb185

Authored by YunaiV
1 parent 04a31f39

✨ feat(mes): 新增生产流转卡状态管理功能

- 添加状态字段到 MesProCardRespVO 和相关的前端组件
- 实现提交、执行和取消生产流转卡的 API 接口
- 更新 MesProCardService 和 MesProCardServiceImpl 以支持新功能
- 更新前端表单和列表以显示和操作流转卡状态
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/card/MesProCardController.java
@@ -80,6 +80,34 @@ public class MesProCardController { @@ -80,6 +80,34 @@ public class MesProCardController {
80 return success(true); 80 return success(true);
81 } 81 }
82 82
  83 + @PutMapping("/submit")
  84 + @Operation(summary = "提交生产流转卡")
  85 + @Parameter(name = "id", description = "编号", required = true)
  86 + @PreAuthorize("@ss.hasPermission('mes:pro-card:update')")
  87 + public CommonResult<Boolean> submitCard(@RequestParam("id") Long id) {
  88 + cardService.submitCard(id);
  89 + return success(true);
  90 + }
  91 +
  92 + // TODO @AI:要不改成 finish,因为它是完成;
  93 + @PutMapping("/execute")
  94 + @Operation(summary = "执行生产流转卡")
  95 + @Parameter(name = "id", description = "编号", required = true)
  96 + @PreAuthorize("@ss.hasPermission('mes:pro-card:update')")
  97 + public CommonResult<Boolean> executeCard(@RequestParam("id") Long id) {
  98 + cardService.executeCard(id);
  99 + return success(true);
  100 + }
  101 +
  102 + @PutMapping("/cancel")
  103 + @Operation(summary = "取消生产流转卡")
  104 + @Parameter(name = "id", description = "编号", required = true)
  105 + @PreAuthorize("@ss.hasPermission('mes:pro-card:update')")
  106 + public CommonResult<Boolean> cancelCard(@RequestParam("id") Long id) {
  107 + cardService.cancelCard(id);
  108 + return success(true);
  109 + }
  110 +
83 @GetMapping("/get") 111 @GetMapping("/get")
84 @Operation(summary = "获得生产流转卡") 112 @Operation(summary = "获得生产流转卡")
85 @Parameter(name = "id", description = "编号", required = true, example = "1024") 113 @Parameter(name = "id", description = "编号", required = true, example = "1024")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/card/vo/MesProCardRespVO.java
@@ -62,6 +62,10 @@ public class MesProCardRespVO { @@ -62,6 +62,10 @@ public class MesProCardRespVO {
62 @ExcelProperty("流转数量") 62 @ExcelProperty("流转数量")
63 private BigDecimal transferedQuantity; 63 private BigDecimal transferedQuantity;
64 64
  65 + @Schema(description = "状态", example = "0")
  66 + @ExcelProperty("状态")
  67 + private Integer status;
  68 +
65 @Schema(description = "备注", example = "备注") 69 @Schema(description = "备注", example = "备注")
66 @ExcelProperty("备注") 70 @ExcelProperty("备注")
67 private String remark; 71 private String remark;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/card/MesProCardDO.java
@@ -54,7 +54,6 @@ public class MesProCardDO extends BaseDO { @@ -54,7 +54,6 @@ public class MesProCardDO extends BaseDO {
54 * 流转数量 54 * 流转数量
55 */ 55 */
56 private BigDecimal transferedQuantity; 56 private BigDecimal transferedQuantity;
57 - // TODO @芋艿:预留字段,暂未使用;  
58 /** 57 /**
59 * 状态 58 * 状态
60 * 59 *
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -274,6 +274,8 @@ public interface ErrorCodeConstants { @@ -274,6 +274,8 @@ public interface ErrorCodeConstants {
274 // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== 274 // ========== MES 生产管理-生产流转卡(1-040-507-000) ==========
275 ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); 275 ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在");
276 ErrorCode PRO_CARD_CODE_DUPLICATE = new ErrorCode(1_040_507_001, "流转卡编码已存在"); 276 ErrorCode PRO_CARD_CODE_DUPLICATE = new ErrorCode(1_040_507_001, "流转卡编码已存在");
  277 + ErrorCode PRO_CARD_STATUS_ERROR = new ErrorCode(1_040_507_002, "流转卡状态不正确");
  278 + ErrorCode PRO_CARD_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_507_003, "已完成或已取消的流转卡不允许取消");
277 // ========== MES 生产管理-流转卡工序(1-040-507-100) ========== 279 // ========== MES 生产管理-流转卡工序(1-040-507-100) ==========
278 ErrorCode PRO_CARD_PROCESS_NOT_EXISTS = new ErrorCode(1_040_507_100, "流转卡工序记录不存在"); 280 ErrorCode PRO_CARD_PROCESS_NOT_EXISTS = new ErrorCode(1_040_507_100, "流转卡工序记录不存在");
279 281
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/card/MesProCardProcessServiceImpl.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.process.MesProCa @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.process.MesProCa
6 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.process.MesProCardProcessSaveReqVO; 6 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.process.MesProCardProcessSaveReqVO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardProcessDO; 7 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardProcessDO;
8 import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardProcessMapper; 8 import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardProcessMapper;
  9 +import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
9 import jakarta.annotation.Resource; 10 import jakarta.annotation.Resource;
10 import org.springframework.context.annotation.Lazy; 11 import org.springframework.context.annotation.Lazy;
11 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
@@ -30,10 +31,18 @@ public class MesProCardProcessServiceImpl implements MesProCardProcessService { @@ -30,10 +31,18 @@ public class MesProCardProcessServiceImpl implements MesProCardProcessService {
30 @Lazy 31 @Lazy
31 private MesProCardService cardService; 32 private MesProCardService cardService;
32 33
  34 + @Resource
  35 + private MesProProcessService processService;
  36 +
33 @Override 37 @Override
34 public Long createCardProcess(MesProCardProcessSaveReqVO createReqVO) { 38 public Long createCardProcess(MesProCardProcessSaveReqVO createReqVO) {
35 - // 1. 校验流转卡存在 39 + // TODO @AI:validateXXXSaveData
  40 + // 1.1 校验流转卡存在
36 cardService.validateCardExists(createReqVO.getCardId()); 41 cardService.validateCardExists(createReqVO.getCardId());
  42 + // 1.2 校验工序存在
  43 + if (createReqVO.getProcessId() != null) {
  44 + processService.validateProcessExists(createReqVO.getProcessId());
  45 + }
37 46
38 // 2. 插入 47 // 2. 插入
39 MesProCardProcessDO cardProcess = BeanUtils.toBean(createReqVO, MesProCardProcessDO.class); 48 MesProCardProcessDO cardProcess = BeanUtils.toBean(createReqVO, MesProCardProcessDO.class);
@@ -45,8 +54,13 @@ public class MesProCardProcessServiceImpl implements MesProCardProcessService { @@ -45,8 +54,13 @@ public class MesProCardProcessServiceImpl implements MesProCardProcessService {
45 public void updateCardProcess(MesProCardProcessSaveReqVO updateReqVO) { 54 public void updateCardProcess(MesProCardProcessSaveReqVO updateReqVO) {
46 // 1.1 校验存在 55 // 1.1 校验存在
47 validateCardProcessExists(updateReqVO.getId()); 56 validateCardProcessExists(updateReqVO.getId());
  57 + // TODO @AI:validateXXXSaveData
48 // 1.2 校验流转卡存在 58 // 1.2 校验流转卡存在
49 cardService.validateCardExists(updateReqVO.getCardId()); 59 cardService.validateCardExists(updateReqVO.getCardId());
  60 + // 1.3 校验工序存在
  61 + if (updateReqVO.getProcessId() != null) {
  62 + processService.validateProcessExists(updateReqVO.getProcessId());
  63 + }
50 64
51 // 2. 更新 65 // 2. 更新
52 MesProCardProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProCardProcessDO.class); 66 MesProCardProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProCardProcessDO.class);
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/card/MesProCardService.java
@@ -67,4 +67,25 @@ public interface MesProCardService { @@ -67,4 +67,25 @@ public interface MesProCardService {
67 */ 67 */
68 List<MesProCardDO> getCardSimpleList(); 68 List<MesProCardDO> getCardSimpleList();
69 69
  70 + /**
  71 + * 提交生产流转卡(草稿 → 已确认)
  72 + *
  73 + * @param id 编号
  74 + */
  75 + void submitCard(Long id);
  76 +
  77 + /**
  78 + * 执行生产流转卡(已确认 → 已完成)
  79 + *
  80 + * @param id 编号
  81 + */
  82 + void executeCard(Long id);
  83 +
  84 + /**
  85 + * 取消生产流转卡(任意非已完成/已取消状态 → 已取消)
  86 + *
  87 + * @param id 编号
  88 + */
  89 + void cancelCard(Long id);
  90 +
70 } 91 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/card/MesProCardServiceImpl.java
@@ -3,13 +3,14 @@ package cn.iocoder.yudao.module.mes.service.pro.card; @@ -3,13 +3,14 @@ package cn.iocoder.yudao.module.mes.service.pro.card;
3 import cn.hutool.core.util.ObjUtil; 3 import cn.hutool.core.util.ObjUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -  
7 -import java.util.List; 6 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardPageReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardPageReqVO;
9 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardSaveReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardSaveReqVO;
10 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardDO; 9 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardDO;
11 import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardMapper; 10 import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardMapper;
  11 +import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum;
12 import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; 12 import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum;
  13 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
13 import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; 14 import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
14 import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService; 15 import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
15 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
@@ -18,9 +19,10 @@ import org.springframework.stereotype.Service; @@ -18,9 +19,10 @@ import org.springframework.stereotype.Service;
18 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
19 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
20 21
  22 +import java.util.List;
  23 +
21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
22 -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_CARD_CODE_DUPLICATE;  
23 -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_CARD_NOT_EXISTS; 25 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
24 26
25 /** 27 /**
26 * MES 生产流转卡 Service 实现类 28 * MES 生产流转卡 Service 实现类
@@ -42,17 +44,23 @@ public class MesProCardServiceImpl implements MesProCardService { @@ -42,17 +44,23 @@ public class MesProCardServiceImpl implements MesProCardService {
42 @Resource 44 @Resource
43 private MesProWorkOrderService workOrderService; 45 private MesProWorkOrderService workOrderService;
44 @Resource 46 @Resource
  47 + private MesMdItemService itemService;
  48 + @Resource
45 private MesWmBarcodeService barcodeService; 49 private MesWmBarcodeService barcodeService;
46 50
47 @Override 51 @Override
48 public Long createCard(MesProCardSaveReqVO createReqVO) { 52 public Long createCard(MesProCardSaveReqVO createReqVO) {
  53 + // TODO @AI:validateXXXSaveData
49 // 1.1 校验编码唯一 54 // 1.1 校验编码唯一
50 validateCardCodeUnique(null, createReqVO.getCode()); 55 validateCardCodeUnique(null, createReqVO.getCode());
51 // 1.2 校验工单存在 56 // 1.2 校验工单存在
52 workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId()); 57 workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId());
  58 + // 1.3 校验物料存在
  59 + itemService.validateItemExists(createReqVO.getItemId());
53 60
54 // 2. 插入 61 // 2. 插入
55 - MesProCardDO card = BeanUtils.toBean(createReqVO, MesProCardDO.class); 62 + MesProCardDO card = BeanUtils.toBean(createReqVO, MesProCardDO.class)
  63 + .setStatus(MesProWorkOrderStatusEnum.PREPARE.getStatus());
56 cardMapper.insert(card); 64 cardMapper.insert(card);
57 65
58 // 3. 自动生成条码 66 // 3. 自动生成条码
@@ -63,10 +71,15 @@ public class MesProCardServiceImpl implements MesProCardService { @@ -63,10 +71,15 @@ public class MesProCardServiceImpl implements MesProCardService {
63 71
64 @Override 72 @Override
65 public void updateCard(MesProCardSaveReqVO updateReqVO) { 73 public void updateCard(MesProCardSaveReqVO updateReqVO) {
  74 + // TODO @AI:validateXXXSaveData
66 // 1.1 校验存在 75 // 1.1 校验存在
67 validateCardExists(updateReqVO.getId()); 76 validateCardExists(updateReqVO.getId());
68 // 1.2 校验编码唯一 77 // 1.2 校验编码唯一
69 validateCardCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); 78 validateCardCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
  79 + // 1.3 校验工单存在
  80 + workOrderService.validateWorkOrderExists(updateReqVO.getWorkOrderId());
  81 + // 1.4 校验物料存在
  82 + itemService.validateItemExists(updateReqVO.getItemId());
70 83
71 // 2. 更新 84 // 2. 更新
72 MesProCardDO updateObj = BeanUtils.toBean(updateReqVO, MesProCardDO.class); 85 MesProCardDO updateObj = BeanUtils.toBean(updateReqVO, MesProCardDO.class);
@@ -99,13 +112,63 @@ public class MesProCardServiceImpl implements MesProCardService { @@ -99,13 +112,63 @@ public class MesProCardServiceImpl implements MesProCardService {
99 return cardMapper.selectList(); 112 return cardMapper.selectList();
100 } 113 }
101 114
  115 + @Override
  116 + public void submitCard(Long id) {
  117 + // 1. 校验存在 + 草稿状态
  118 + validateCardExistsAndStatus(id, MesProWorkOrderStatusEnum.PREPARE);
  119 +
  120 + // 2. 提交(草稿 → 已确认)
  121 + cardMapper.updateById(new MesProCardDO()
  122 + .setId(id).setStatus(MesProWorkOrderStatusEnum.CONFIRMED.getStatus()));
  123 + }
  124 +
  125 + @Override
  126 + public void executeCard(Long id) {
  127 + // 1. 校验存在 + 已确认状态
  128 + validateCardExistsAndStatus(id, MesProWorkOrderStatusEnum.CONFIRMED);
  129 +
  130 + // 2. 执行(已确认 → 已完成)
  131 + cardMapper.updateById(new MesProCardDO()
  132 + .setId(id).setStatus(MesProWorkOrderStatusEnum.FINISHED.getStatus()));
  133 + }
  134 +
  135 + @Override
  136 + public void cancelCard(Long id) {
  137 + // 1.1 校验存在
  138 + MesProCardDO card = validateCardExistsInternal(id);
  139 + // 1.2 已完成和已取消不允许取消
  140 + if (ObjectUtils.equalsAny(card.getStatus(),
  141 + MesProWorkOrderStatusEnum.FINISHED.getStatus(),
  142 + MesProWorkOrderStatusEnum.CANCELED.getStatus())) {
  143 + throw exception(PRO_CARD_CANCEL_NOT_ALLOWED);
  144 + }
  145 +
  146 + // 2. 取消
  147 + cardMapper.updateById(new MesProCardDO()
  148 + .setId(id).setStatus(MesProWorkOrderStatusEnum.CANCELED.getStatus()));
  149 + }
  150 +
102 // ==================== 校验方法 ==================== 151 // ==================== 校验方法 ====================
103 152
104 @Override 153 @Override
105 public void validateCardExists(Long id) { 154 public void validateCardExists(Long id) {
106 - if (cardMapper.selectById(id) == null) { 155 + validateCardExistsInternal(id);
  156 + }
  157 +
  158 + private MesProCardDO validateCardExistsInternal(Long id) {
  159 + MesProCardDO card = cardMapper.selectById(id);
  160 + if (card == null) {
107 throw exception(PRO_CARD_NOT_EXISTS); 161 throw exception(PRO_CARD_NOT_EXISTS);
108 } 162 }
  163 + return card;
  164 + }
  165 +
  166 + private MesProCardDO validateCardExistsAndStatus(Long id, MesProWorkOrderStatusEnum status) {
  167 + MesProCardDO card = validateCardExistsInternal(id);
  168 + if (ObjUtil.notEqual(status.getStatus(), card.getStatus())) {
  169 + throw exception(PRO_CARD_STATUS_ERROR);
  170 + }
  171 + return card;
109 } 172 }
110 173
111 private void validateCardCodeUnique(Long id, String code) { 174 private void validateCardCodeUnique(Long id, String code) {