From dfa61b7d7e9d8dbb3c2bc3aa68d31d1ff29b0c24 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Mar 2026 23:01:59 +0800 Subject: [PATCH] ✨ feat(wm): 添加物料消耗记录及相关服务实现 --- yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java | 1 + yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java | 1 + yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java | 3 ++- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java | 21 +++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java | 15 +++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 1 + yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java | 5 +++-- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java | 78 +++++++++++++++++++++++++++++++++++++++++------------------------------------- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java | 29 +++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java | 33 +++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java | 33 +++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 449 insertions(+), 40 deletions(-) create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java index 85de49e..677dbf3 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java @@ -7,6 +7,7 @@ package cn.iocoder.yudao.module.infra.api.config; */ public interface ConfigApi { + /** * 根据参数键查询参数值 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java index 38582c2..c608ba0 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; */ public interface WebSocketSenderApi { + /** * 发送消息给指定用户 * diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java index f197a82..99dde54 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java @@ -48,6 +48,7 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPOR import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - MES 生产报工") @RestController @@ -156,7 +157,7 @@ public class MesProFeedbackController { @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") public CommonResult approveFeedback(@RequestParam("id") Long id) { - return success(feedbackService.approveFeedback(id)); + return success(feedbackService.approveFeedback(id, getLoginUserId())); } // ==================== 拼接 VO ==================== diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java new file mode 100644 index 0000000..577cf8d --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; +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.*; + +import java.time.LocalDateTime; + +/** + * MES 物料消耗记录 DO + * + * @author 芋道源码 + */ +@TableName("mes_wm_item_consume") +@KeySequence("mes_wm_item_consume_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmItemConsumeDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 生产工单编号 + * + * 关联 {@link MesProWorkOrderDO#getId()} + */ + private Long workOrderId; + /** + * 生产任务编号 + * + * 关联 {@link MesProTaskDO#getId()} + */ + private Long taskId; + /** + * 工作站编号 + * + * 关联 {@link MesMdWorkstationDO#getId()} + */ + private Long workstationId; + /** + * 工序编号 + * + * 关联 {@link MesProProcessDO#getId()} + */ + private Long processId; + /** + * 报工记录编号 + * + * 关联 {@link MesProFeedbackDO#getId()} + */ + private Long feedbackId; + /** + * 消耗日期 + */ + private LocalDateTime consumeDate; + // DONE @AI:搞个独立的枚举类; + /** + * 状态 + * + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java new file mode 100644 index 0000000..635787b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 物料消耗记录行 DO + * + * @author 芋道源码 + */ +@TableName("mes_wm_item_consume_line") +@KeySequence("mes_wm_item_consume_line_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmItemConsumeLineDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 消耗记录编号 + * + * 关联 {@link MesWmItemConsumeDO#getId()} + */ + private Long consumeId; + /** + * 物料编号 + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 消耗数量 + */ + private BigDecimal quantity; + /** + * 批次编号 + * + * 关联 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getId()} + */ + private Long batchId; + /** + * 批次号 + * + * 冗余 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getCode()} + */ + private String batchCode; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java new file mode 100644 index 0000000..493cb4f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 物料消耗记录行 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesWmItemConsumeLineMapper extends BaseMapperX { + + default List selectListByConsumeId(Long consumeId) { + return selectList(MesWmItemConsumeLineDO::getConsumeId, consumeId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java new file mode 100644 index 0000000..41dc595 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * MES 物料消耗记录 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesWmItemConsumeMapper extends BaseMapperX { + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 096dc6f..661b939 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -250,6 +250,7 @@ public interface ErrorCodeConstants { ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工"); ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0"); ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0"); + ErrorCode PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS = new ErrorCode(1_040_506_012, "当前报工单未完成检验(待检数量:{}),无法执行报工"); // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java new file mode 100644 index 0000000..80b16b6 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.mes.enums.wm; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 物料消耗记录状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesWmItemConsumeStatusEnum implements ArrayValuable { + + /** + * 草稿 + */ + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), + /** + * 已完成 + */ + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemConsumeStatusEnum::getStatus).toArray(Integer[]::new); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java index 814ede0..89fe35d 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java @@ -68,10 +68,11 @@ public interface MesProFeedbackService { /** * 审批报工(审批中 -> 已完成 或 待检验) * - * @param id 编号 + * @param id 编号 + * @param userId 当前操作用户编号 * @return true=已完成, false=待检验 */ - boolean approveFeedback(Long id); + boolean approveFeedback(Long id, Long userId); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java index a3dbff2..8828e2b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.mes.service.pro.feedback; -import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedba import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; +import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -54,6 +55,9 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { @Lazy // 避免循环依赖 private MesProTaskService taskService; + @Resource + private MesWmItemConsumeService itemConsumeService; + @Override public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { // 1. 校验 @@ -121,43 +125,55 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())); } - // DONE @AI:改成 boolean:true 表示已完成;false 表示待检验,前端需提示"报工成功,请等待质量检验完成!" @Override @Transactional(rollbackFor = Exception.class) - public boolean approveFeedback(Long id) { - // TODO @AI: 逻辑需要继续跟进; - // 1.1 校验存在 + 审批中状态 + public boolean approveFeedback(Long id, Long userId) { + // 1.1.a 校验存在 + 审批中状态 MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); - // 1.2 校验报工数量 > 0 + // 1.1.b 校验报工数量 > 0 if (feedback.getFeedbackQuantity() == null || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE); } - // 1.3 校验任务未完成 + // 1.2.a 校验任务未完成 taskService.validateTaskNotFinished(feedback.getTaskId()); - // 1.4 仍有待检数量时不能执行 + // 1.2.b 仍有待检数量时不能执行 if (feedback.getUncheckQuantity() != null && feedback.getUncheckQuantity().compareTo(BigDecimal.ZERO) > 0) { - throw exception(PRO_FEEDBACK_NOT_APPROVING); // TODO @芋艿:新增一个专用错误码,例如 PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS + throw exception(PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS, feedback.getUncheckQuantity()); } - // 2.1 查询工序的 checkFlag,决定目标状态 - boolean checkFlag = getCheckFlag(feedback.getRouteId(), feedback.getProcessId()); - Integer targetStatus = checkFlag - ? MesProFeedbackStatusEnum.UNCHECK.getStatus() // 需要检验 → 待检验 - : MesProFeedbackStatusEnum.FINISHED.getStatus(); // 无需检验 → 已完成 - // 2.2 更新状态 + 审核人 - feedbackMapper.updateById(new MesProFeedbackDO().setId(id) - .setStatus(targetStatus) - .setApproveUserId(getLoginUserId())); - - // 3. 如果不需要检验(直接完成),执行后续操作 - if (BooleanUtil.isFalse(checkFlag)) { - // TODO @芋艿:WM 物料消耗(WmItemConsumeService)未迁移,此处需补充物料消耗逻辑 - // TODO @芋艿:WM 产品产出(WmProductProduceService)未迁移,此处需补充产品产出逻辑 - // TODO @芋艿:updateProTaskAndWorkorder 待 pro_task 服务迁移后补充级联更新任务/工单的已生产数量 + // 2. 物料消耗:根据工序 BOM 生成消耗记录 + MesWmItemConsumeDO itemConsume = itemConsumeService.generateItemConsume(feedback); + if (itemConsume != null) { + itemConsumeService.finishItemConsume(itemConsume.getId()); + } + + // 3. 查询工序的 keyFlag + checkFlag + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( + feedback.getRouteId(), feedback.getProcessId()); + boolean keyFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getKeyFlag()); + boolean checkFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); + + // 4. 情况一:关键工序 + 需要检验 → 待检验状态(等质检完成后入库) + if (keyFlag && checkFlag) { + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) + .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus()) + .setApproveUserId(userId)); + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce(质量状态=待检验) + return false; + } + + // 4.1 情况二:关键工序 + 无需检验 → 直接完成 + if (keyFlag) { + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce + executeProductProduce + // TODO @芋艿:updateProTaskAndWorkorder 待补充级联更新任务/工单的已生产数量 } - return BooleanUtil.isFalse(checkFlag); // true=已完成, false=待检验 + // 4.2 更新状态为已完成 + 审核人 + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) + .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus()) + .setApproveUserId(userId)); + return true; // 已完成 } // ==================== 校验方法 ==================== @@ -226,16 +242,4 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { return taskService.validateTaskNotFinished(reqVO.getTaskId()); } - /** - * 获取指定工艺路线中指定工序的 checkFlag - * - * @param routeId 工艺路线编号 - * @param processId 工序编号 - * @return 是否需要检验 - */ - private boolean getCheckFlag(Long routeId, Long processId) { - MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId); - return routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); - } - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java new file mode 100644 index 0000000..16c5d99 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; + +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; + +import java.util.List; + +/** + * MES 物料消耗记录行 Service 接口 + * + * @author 芋道源码 + */ +public interface MesWmItemConsumeLineService { + + /** + * 批量创建消耗行 + * + * @param lines 消耗行列表 + */ + void createItemConsumeLineBatch(List lines); + + /** + * 根据消耗记录编号查询消耗行 + * + * @param consumeId 消耗记录编号 + * @return 消耗行列表 + */ + List getItemConsumeLineListByConsumeId(Long consumeId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java new file mode 100644 index 0000000..f84ccfc --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; + +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeLineMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * MES 物料消耗记录行 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesWmItemConsumeLineServiceImpl implements MesWmItemConsumeLineService { + + @Resource + private MesWmItemConsumeLineMapper itemConsumeLineMapper; + + @Override + public void createItemConsumeLineBatch(List lines) { + itemConsumeLineMapper.insertBatch(lines); + } + + @Override + public List getItemConsumeLineListByConsumeId(Long consumeId) { + return itemConsumeLineMapper.selectListByConsumeId(consumeId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java new file mode 100644 index 0000000..3e66349 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; + +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; + +/** + * MES 物料消耗记录 Service 接口 + * + * @author 芋道源码 + */ +public interface MesWmItemConsumeService { + + /** + * 根据报工单生成物料消耗记录 + * + * 1. 查询当前工序的 BOM 物料配置 + * 2. 生成消耗单头 + 行(消耗数量 = BOM 用料比例 × 报工数量) + * + * @param feedback 报工记录 + * @return 生成的消耗记录,无 BOM 时返回 null + */ + MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback); + + /** + * 完成物料消耗(库存扣减) + * + * 遍历消耗行,扣减线边库库存,更新消耗单状态为已完成 + * + * @param consumeId 消耗记录编号 + */ + void finishItemConsume(Long consumeId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java new file mode 100644 index 0000000..fcbad4d --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeMapper; +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum; +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; + +/** + * MES 物料消耗记录 Service 实现类 + * + * 参考 KTG {@code WmItemConsumeServiceImpl#generateItemConsume} + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesWmItemConsumeServiceImpl implements MesWmItemConsumeService { + + @Resource + private MesWmItemConsumeMapper itemConsumeMapper; + @Resource + private MesWmItemConsumeLineService itemConsumeLineService; + @Resource + private MesProRouteProductBomService routeProductBomService; + + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后,注入并调用 + // @Resource + // private MesWmMaterialStockService materialStockService; + + @Override + public MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback) { + // 1. 查询当前工序的 BOM 物料配置 + List boms = routeProductBomService.getRouteProductBomList( + feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId()); + if (CollUtil.isEmpty(boms)) { + return null; + } + + // 2.1 生成消耗单头 + MesWmItemConsumeDO consume = MesWmItemConsumeDO.builder() + .workOrderId(feedback.getWorkOrderId()).taskId(feedback.getTaskId()) + .workstationId(feedback.getWorkstationId()).processId(feedback.getProcessId()) + .feedbackId(feedback.getId()).consumeDate(LocalDateTime.now()) + .status(MesWmItemConsumeStatusEnum.PREPARE.getStatus()).build(); + itemConsumeMapper.insert(consume); + // 2.2 批量生成消耗行(消耗数量 = BOM 用料比例 × 报工数量) + List lines = convertList(boms, bom -> MesWmItemConsumeLineDO.builder() + .consumeId(consume.getId()).itemId(bom.getItemId()) + .quantity(bom.getQuantity().multiply(feedback.getFeedbackQuantity())).build()); + itemConsumeLineService.createItemConsumeLineBatch(lines); + return consume; + } + + @Override + public void finishItemConsume(Long consumeId) { + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后实现库存扣减 + // List lines = itemConsumeLineService.getItemConsumeLineListByConsumeId(consumeId); + // for (MesWmItemConsumeLineDO line : lines) { + // materialStockService.decreaseStock(line.getItemId(), ..., line.getQuantity()); + // } + // 更新消耗单状态为已完成 + itemConsumeMapper.updateById(MesWmItemConsumeDO.builder() + .id(consumeId).status(MesWmItemConsumeStatusEnum.FINISHED.getStatus()).build()); + } + +} -- libgit2 0.21.4