Commit dfa61b7d7e9d8dbb3c2bc3aa68d31d1ff29b0c24
1 parent
92a5a2bd
✨ feat(wm): 添加物料消耗记录及相关服务实现
Showing
15 changed files
with
449 additions
and
40 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java
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; | @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 11 | */ | 11 | */ |
| 12 | public interface WebSocketSenderApi { | 12 | public interface WebSocketSenderApi { |
| 13 | 13 | ||
| 14 | + | ||
| 14 | /** | 15 | /** |
| 15 | * 发送消息给指定用户 | 16 | * 发送消息给指定用户 |
| 16 | * | 17 | * |
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 | @@ -48,6 +48,7 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPOR | ||
| 48 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 48 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 49 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 49 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 50 | import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | 50 | import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; |
| 51 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 51 | 52 | ||
| 52 | @Tag(name = "管理后台 - MES 生产报工") | 53 | @Tag(name = "管理后台 - MES 生产报工") |
| 53 | @RestController | 54 | @RestController |
| @@ -156,7 +157,7 @@ public class MesProFeedbackController { | @@ -156,7 +157,7 @@ public class MesProFeedbackController { | ||
| 156 | @Parameter(name = "id", description = "编号", required = true) | 157 | @Parameter(name = "id", description = "编号", required = true) |
| 157 | @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") | 158 | @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") |
| 158 | public CommonResult<Boolean> approveFeedback(@RequestParam("id") Long id) { | 159 | public CommonResult<Boolean> approveFeedback(@RequestParam("id") Long id) { |
| 159 | - return success(feedbackService.approveFeedback(id)); | 160 | + return success(feedbackService.approveFeedback(id, getLoginUserId())); |
| 160 | } | 161 | } |
| 161 | 162 | ||
| 162 | // ==================== 拼接 VO ==================== | 163 | // ==================== 拼接 VO ==================== |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; | ||
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | ||
| 6 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; | ||
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; | ||
| 8 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | ||
| 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 | +/** | ||
| 17 | + * MES 物料消耗记录 DO | ||
| 18 | + * | ||
| 19 | + * @author 芋道源码 | ||
| 20 | + */ | ||
| 21 | +@TableName("mes_wm_item_consume") | ||
| 22 | +@KeySequence("mes_wm_item_consume_seq") | ||
| 23 | +@Data | ||
| 24 | +@EqualsAndHashCode(callSuper = true) | ||
| 25 | +@ToString(callSuper = true) | ||
| 26 | +@Builder | ||
| 27 | +@NoArgsConstructor | ||
| 28 | +@AllArgsConstructor | ||
| 29 | +public class MesWmItemConsumeDO extends BaseDO { | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 编号 | ||
| 33 | + */ | ||
| 34 | + @TableId | ||
| 35 | + private Long id; | ||
| 36 | + /** | ||
| 37 | + * 生产工单编号 | ||
| 38 | + * | ||
| 39 | + * 关联 {@link MesProWorkOrderDO#getId()} | ||
| 40 | + */ | ||
| 41 | + private Long workOrderId; | ||
| 42 | + /** | ||
| 43 | + * 生产任务编号 | ||
| 44 | + * | ||
| 45 | + * 关联 {@link MesProTaskDO#getId()} | ||
| 46 | + */ | ||
| 47 | + private Long taskId; | ||
| 48 | + /** | ||
| 49 | + * 工作站编号 | ||
| 50 | + * | ||
| 51 | + * 关联 {@link MesMdWorkstationDO#getId()} | ||
| 52 | + */ | ||
| 53 | + private Long workstationId; | ||
| 54 | + /** | ||
| 55 | + * 工序编号 | ||
| 56 | + * | ||
| 57 | + * 关联 {@link MesProProcessDO#getId()} | ||
| 58 | + */ | ||
| 59 | + private Long processId; | ||
| 60 | + /** | ||
| 61 | + * 报工记录编号 | ||
| 62 | + * | ||
| 63 | + * 关联 {@link MesProFeedbackDO#getId()} | ||
| 64 | + */ | ||
| 65 | + private Long feedbackId; | ||
| 66 | + /** | ||
| 67 | + * 消耗日期 | ||
| 68 | + */ | ||
| 69 | + private LocalDateTime consumeDate; | ||
| 70 | + // DONE @AI:搞个独立的枚举类; | ||
| 71 | + /** | ||
| 72 | + * 状态 | ||
| 73 | + * | ||
| 74 | + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum} | ||
| 75 | + */ | ||
| 76 | + private Integer status; | ||
| 77 | + /** | ||
| 78 | + * 备注 | ||
| 79 | + */ | ||
| 80 | + private String remark; | ||
| 81 | + | ||
| 82 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; | ||
| 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 | + * @author 芋道源码 | ||
| 16 | + */ | ||
| 17 | +@TableName("mes_wm_item_consume_line") | ||
| 18 | +@KeySequence("mes_wm_item_consume_line_seq") | ||
| 19 | +@Data | ||
| 20 | +@EqualsAndHashCode(callSuper = true) | ||
| 21 | +@ToString(callSuper = true) | ||
| 22 | +@Builder | ||
| 23 | +@NoArgsConstructor | ||
| 24 | +@AllArgsConstructor | ||
| 25 | +public class MesWmItemConsumeLineDO extends BaseDO { | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 编号 | ||
| 29 | + */ | ||
| 30 | + @TableId | ||
| 31 | + private Long id; | ||
| 32 | + /** | ||
| 33 | + * 消耗记录编号 | ||
| 34 | + * | ||
| 35 | + * 关联 {@link MesWmItemConsumeDO#getId()} | ||
| 36 | + */ | ||
| 37 | + private Long consumeId; | ||
| 38 | + /** | ||
| 39 | + * 物料编号 | ||
| 40 | + * | ||
| 41 | + * 关联 {@link MesMdItemDO#getId()} | ||
| 42 | + */ | ||
| 43 | + private Long itemId; | ||
| 44 | + /** | ||
| 45 | + * 消耗数量 | ||
| 46 | + */ | ||
| 47 | + private BigDecimal quantity; | ||
| 48 | + /** | ||
| 49 | + * 批次编号 | ||
| 50 | + * | ||
| 51 | + * 关联 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getId()} | ||
| 52 | + */ | ||
| 53 | + private Long batchId; | ||
| 54 | + /** | ||
| 55 | + * 批次号 | ||
| 56 | + * | ||
| 57 | + * 冗余 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getCode()} | ||
| 58 | + */ | ||
| 59 | + private String batchCode; | ||
| 60 | + /** | ||
| 61 | + * 备注 | ||
| 62 | + */ | ||
| 63 | + private String remark; | ||
| 64 | + | ||
| 65 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * MES 物料消耗记录行 Mapper | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +@Mapper | ||
| 15 | +public interface MesWmItemConsumeLineMapper extends BaseMapperX<MesWmItemConsumeLineDO> { | ||
| 16 | + | ||
| 17 | + default List<MesWmItemConsumeLineDO> selectListByConsumeId(Long consumeId) { | ||
| 18 | + return selectList(MesWmItemConsumeLineDO::getConsumeId, consumeId); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * MES 物料消耗记录 Mapper | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Mapper | ||
| 13 | +public interface MesWmItemConsumeMapper extends BaseMapperX<MesWmItemConsumeDO> { | ||
| 14 | + | ||
| 15 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| @@ -250,6 +250,7 @@ public interface ErrorCodeConstants { | @@ -250,6 +250,7 @@ public interface ErrorCodeConstants { | ||
| 250 | ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工"); | 250 | ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工"); |
| 251 | ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0"); | 251 | ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0"); |
| 252 | ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0"); | 252 | ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0"); |
| 253 | + ErrorCode PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS = new ErrorCode(1_040_506_012, "当前报工单未完成检验(待检数量:{}),无法执行报工"); | ||
| 253 | 254 | ||
| 254 | // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== | 255 | // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== |
| 255 | ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); | 256 | ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.enums.wm; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 4 | +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; | ||
| 5 | +import lombok.AllArgsConstructor; | ||
| 6 | +import lombok.Getter; | ||
| 7 | + | ||
| 8 | +import java.util.Arrays; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * MES 物料消耗记录状态枚举 | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@Getter | ||
| 16 | +@AllArgsConstructor | ||
| 17 | +public enum MesWmItemConsumeStatusEnum implements ArrayValuable<Integer> { | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 草稿 | ||
| 21 | + */ | ||
| 22 | + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), | ||
| 23 | + /** | ||
| 24 | + * 已完成 | ||
| 25 | + */ | ||
| 26 | + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); | ||
| 27 | + | ||
| 28 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemConsumeStatusEnum::getStatus).toArray(Integer[]::new); | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 状态值 | ||
| 32 | + */ | ||
| 33 | + private final Integer status; | ||
| 34 | + /** | ||
| 35 | + * 状态名 | ||
| 36 | + */ | ||
| 37 | + private final String name; | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public Integer[] array() { | ||
| 41 | + return ARRAYS; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
| @@ -68,10 +68,11 @@ public interface MesProFeedbackService { | @@ -68,10 +68,11 @@ public interface MesProFeedbackService { | ||
| 68 | /** | 68 | /** |
| 69 | * 审批报工(审批中 -> 已完成 或 待检验) | 69 | * 审批报工(审批中 -> 已完成 或 待检验) |
| 70 | * | 70 | * |
| 71 | - * @param id 编号 | 71 | + * @param id 编号 |
| 72 | + * @param userId 当前操作用户编号 | ||
| 72 | * @return true=已完成, false=待检验 | 73 | * @return true=已完成, false=待检验 |
| 73 | */ | 74 | */ |
| 74 | - boolean approveFeedback(Long id); | 75 | + boolean approveFeedback(Long id, Long userId); |
| 75 | 76 | ||
| 76 | } | 77 | } |
| 77 | 78 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.pro.feedback; | 1 | package cn.iocoder.yudao.module.mes.service.pro.feedback; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.BooleanUtil; | ||
| 4 | import cn.hutool.core.util.ObjUtil; | 3 | import cn.hutool.core.util.ObjUtil; |
| 5 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| @@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedba | @@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedba | ||
| 9 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; | 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| 11 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | ||
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; | 13 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; |
| 14 | import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; | 14 | import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; |
| @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic | @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic | ||
| 16 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; | 16 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; |
| 17 | import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; | 17 | import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; |
| 18 | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; | 18 | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService; | ||
| 19 | import jakarta.annotation.Resource; | 20 | import jakarta.annotation.Resource; |
| 20 | import org.springframework.context.annotation.Lazy; | 21 | import org.springframework.context.annotation.Lazy; |
| 21 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
| @@ -54,6 +55,9 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -54,6 +55,9 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 54 | @Lazy // 避免循环依赖 | 55 | @Lazy // 避免循环依赖 |
| 55 | private MesProTaskService taskService; | 56 | private MesProTaskService taskService; |
| 56 | 57 | ||
| 58 | + @Resource | ||
| 59 | + private MesWmItemConsumeService itemConsumeService; | ||
| 60 | + | ||
| 57 | @Override | 61 | @Override |
| 58 | public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { | 62 | public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { |
| 59 | // 1. 校验 | 63 | // 1. 校验 |
| @@ -121,43 +125,55 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -121,43 +125,55 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 121 | .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())); | 125 | .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())); |
| 122 | } | 126 | } |
| 123 | 127 | ||
| 124 | - // DONE @AI:改成 boolean:true 表示已完成;false 表示待检验,前端需提示"报工成功,请等待质量检验完成!" | ||
| 125 | @Override | 128 | @Override |
| 126 | @Transactional(rollbackFor = Exception.class) | 129 | @Transactional(rollbackFor = Exception.class) |
| 127 | - public boolean approveFeedback(Long id) { | ||
| 128 | - // TODO @AI: 逻辑需要继续跟进; | ||
| 129 | - // 1.1 校验存在 + 审批中状态 | 130 | + public boolean approveFeedback(Long id, Long userId) { |
| 131 | + // 1.1.a 校验存在 + 审批中状态 | ||
| 130 | MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); | 132 | MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); |
| 131 | - // 1.2 校验报工数量 > 0 | 133 | + // 1.1.b 校验报工数量 > 0 |
| 132 | if (feedback.getFeedbackQuantity() == null | 134 | if (feedback.getFeedbackQuantity() == null |
| 133 | || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { | 135 | || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| 134 | throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE); | 136 | throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE); |
| 135 | } | 137 | } |
| 136 | - // 1.3 校验任务未完成 | 138 | + // 1.2.a 校验任务未完成 |
| 137 | taskService.validateTaskNotFinished(feedback.getTaskId()); | 139 | taskService.validateTaskNotFinished(feedback.getTaskId()); |
| 138 | - // 1.4 仍有待检数量时不能执行 | 140 | + // 1.2.b 仍有待检数量时不能执行 |
| 139 | if (feedback.getUncheckQuantity() != null | 141 | if (feedback.getUncheckQuantity() != null |
| 140 | && feedback.getUncheckQuantity().compareTo(BigDecimal.ZERO) > 0) { | 142 | && feedback.getUncheckQuantity().compareTo(BigDecimal.ZERO) > 0) { |
| 141 | - throw exception(PRO_FEEDBACK_NOT_APPROVING); // TODO @芋艿:新增一个专用错误码,例如 PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS | 143 | + throw exception(PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS, feedback.getUncheckQuantity()); |
| 142 | } | 144 | } |
| 143 | 145 | ||
| 144 | - // 2.1 查询工序的 checkFlag,决定目标状态 | ||
| 145 | - boolean checkFlag = getCheckFlag(feedback.getRouteId(), feedback.getProcessId()); | ||
| 146 | - Integer targetStatus = checkFlag | ||
| 147 | - ? MesProFeedbackStatusEnum.UNCHECK.getStatus() // 需要检验 → 待检验 | ||
| 148 | - : MesProFeedbackStatusEnum.FINISHED.getStatus(); // 无需检验 → 已完成 | ||
| 149 | - // 2.2 更新状态 + 审核人 | ||
| 150 | - feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | ||
| 151 | - .setStatus(targetStatus) | ||
| 152 | - .setApproveUserId(getLoginUserId())); | ||
| 153 | - | ||
| 154 | - // 3. 如果不需要检验(直接完成),执行后续操作 | ||
| 155 | - if (BooleanUtil.isFalse(checkFlag)) { | ||
| 156 | - // TODO @芋艿:WM 物料消耗(WmItemConsumeService)未迁移,此处需补充物料消耗逻辑 | ||
| 157 | - // TODO @芋艿:WM 产品产出(WmProductProduceService)未迁移,此处需补充产品产出逻辑 | ||
| 158 | - // TODO @芋艿:updateProTaskAndWorkorder 待 pro_task 服务迁移后补充级联更新任务/工单的已生产数量 | 146 | + // 2. 物料消耗:根据工序 BOM 生成消耗记录 |
| 147 | + MesWmItemConsumeDO itemConsume = itemConsumeService.generateItemConsume(feedback); | ||
| 148 | + if (itemConsume != null) { | ||
| 149 | + itemConsumeService.finishItemConsume(itemConsume.getId()); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + // 3. 查询工序的 keyFlag + checkFlag | ||
| 153 | + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( | ||
| 154 | + feedback.getRouteId(), feedback.getProcessId()); | ||
| 155 | + boolean keyFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getKeyFlag()); | ||
| 156 | + boolean checkFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); | ||
| 157 | + | ||
| 158 | + // 4. 情况一:关键工序 + 需要检验 → 待检验状态(等质检完成后入库) | ||
| 159 | + if (keyFlag && checkFlag) { | ||
| 160 | + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | ||
| 161 | + .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus()) | ||
| 162 | + .setApproveUserId(userId)); | ||
| 163 | + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce(质量状态=待检验) | ||
| 164 | + return false; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + // 4.1 情况二:关键工序 + 无需检验 → 直接完成 | ||
| 168 | + if (keyFlag) { | ||
| 169 | + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce + executeProductProduce | ||
| 170 | + // TODO @芋艿:updateProTaskAndWorkorder 待补充级联更新任务/工单的已生产数量 | ||
| 159 | } | 171 | } |
| 160 | - return BooleanUtil.isFalse(checkFlag); // true=已完成, false=待检验 | 172 | + // 4.2 更新状态为已完成 + 审核人 |
| 173 | + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | ||
| 174 | + .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus()) | ||
| 175 | + .setApproveUserId(userId)); | ||
| 176 | + return true; // 已完成 | ||
| 161 | } | 177 | } |
| 162 | 178 | ||
| 163 | // ==================== 校验方法 ==================== | 179 | // ==================== 校验方法 ==================== |
| @@ -226,16 +242,4 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -226,16 +242,4 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 226 | return taskService.validateTaskNotFinished(reqVO.getTaskId()); | 242 | return taskService.validateTaskNotFinished(reqVO.getTaskId()); |
| 227 | } | 243 | } |
| 228 | 244 | ||
| 229 | - /** | ||
| 230 | - * 获取指定工艺路线中指定工序的 checkFlag | ||
| 231 | - * | ||
| 232 | - * @param routeId 工艺路线编号 | ||
| 233 | - * @param processId 工序编号 | ||
| 234 | - * @return 是否需要检验 | ||
| 235 | - */ | ||
| 236 | - private boolean getCheckFlag(Long routeId, Long processId) { | ||
| 237 | - MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId); | ||
| 238 | - return routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); | ||
| 239 | - } | ||
| 240 | - | ||
| 241 | } | 245 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | ||
| 4 | + | ||
| 5 | +import java.util.List; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * MES 物料消耗记录行 Service 接口 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public interface MesWmItemConsumeLineService { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 批量创建消耗行 | ||
| 16 | + * | ||
| 17 | + * @param lines 消耗行列表 | ||
| 18 | + */ | ||
| 19 | + void createItemConsumeLineBatch(List<MesWmItemConsumeLineDO> lines); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 根据消耗记录编号查询消耗行 | ||
| 23 | + * | ||
| 24 | + * @param consumeId 消耗记录编号 | ||
| 25 | + * @return 消耗行列表 | ||
| 26 | + */ | ||
| 27 | + List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId); | ||
| 28 | + | ||
| 29 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeLineMapper; | ||
| 5 | +import jakarta.annotation.Resource; | ||
| 6 | +import org.springframework.stereotype.Service; | ||
| 7 | +import org.springframework.validation.annotation.Validated; | ||
| 8 | + | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * MES 物料消耗记录行 Service 实现类 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Service | ||
| 17 | +@Validated | ||
| 18 | +public class MesWmItemConsumeLineServiceImpl implements MesWmItemConsumeLineService { | ||
| 19 | + | ||
| 20 | + @Resource | ||
| 21 | + private MesWmItemConsumeLineMapper itemConsumeLineMapper; | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public void createItemConsumeLineBatch(List<MesWmItemConsumeLineDO> lines) { | ||
| 25 | + itemConsumeLineMapper.insertBatch(lines); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId) { | ||
| 30 | + return itemConsumeLineMapper.selectListByConsumeId(consumeId); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * MES 物料消耗记录 Service 接口 | ||
| 8 | + * | ||
| 9 | + * @author 芋道源码 | ||
| 10 | + */ | ||
| 11 | +public interface MesWmItemConsumeService { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 根据报工单生成物料消耗记录 | ||
| 15 | + * | ||
| 16 | + * 1. 查询当前工序的 BOM 物料配置 | ||
| 17 | + * 2. 生成消耗单头 + 行(消耗数量 = BOM 用料比例 × 报工数量) | ||
| 18 | + * | ||
| 19 | + * @param feedback 报工记录 | ||
| 20 | + * @return 生成的消耗记录,无 BOM 时返回 null | ||
| 21 | + */ | ||
| 22 | + MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 完成物料消耗(库存扣减) | ||
| 26 | + * | ||
| 27 | + * 遍历消耗行,扣减线边库库存,更新消耗单状态为已完成 | ||
| 28 | + * | ||
| 29 | + * @param consumeId 消耗记录编号 | ||
| 30 | + */ | ||
| 31 | + void finishItemConsume(Long consumeId); | ||
| 32 | + | ||
| 33 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | ||
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; | ||
| 6 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | ||
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | ||
| 8 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeMapper; | ||
| 9 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum; | ||
| 10 | +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService; | ||
| 11 | +import jakarta.annotation.Resource; | ||
| 12 | +import org.springframework.stereotype.Service; | ||
| 13 | +import org.springframework.validation.annotation.Validated; | ||
| 14 | + | ||
| 15 | +import java.time.LocalDateTime; | ||
| 16 | +import java.util.List; | ||
| 17 | + | ||
| 18 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * MES 物料消耗记录 Service 实现类 | ||
| 22 | + * | ||
| 23 | + * 参考 KTG {@code WmItemConsumeServiceImpl#generateItemConsume} | ||
| 24 | + * | ||
| 25 | + * @author 芋道源码 | ||
| 26 | + */ | ||
| 27 | +@Service | ||
| 28 | +@Validated | ||
| 29 | +public class MesWmItemConsumeServiceImpl implements MesWmItemConsumeService { | ||
| 30 | + | ||
| 31 | + @Resource | ||
| 32 | + private MesWmItemConsumeMapper itemConsumeMapper; | ||
| 33 | + @Resource | ||
| 34 | + private MesWmItemConsumeLineService itemConsumeLineService; | ||
| 35 | + @Resource | ||
| 36 | + private MesProRouteProductBomService routeProductBomService; | ||
| 37 | + | ||
| 38 | + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后,注入并调用 | ||
| 39 | + // @Resource | ||
| 40 | + // private MesWmMaterialStockService materialStockService; | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback) { | ||
| 44 | + // 1. 查询当前工序的 BOM 物料配置 | ||
| 45 | + List<MesProRouteProductBomDO> boms = routeProductBomService.getRouteProductBomList( | ||
| 46 | + feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId()); | ||
| 47 | + if (CollUtil.isEmpty(boms)) { | ||
| 48 | + return null; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // 2.1 生成消耗单头 | ||
| 52 | + MesWmItemConsumeDO consume = MesWmItemConsumeDO.builder() | ||
| 53 | + .workOrderId(feedback.getWorkOrderId()).taskId(feedback.getTaskId()) | ||
| 54 | + .workstationId(feedback.getWorkstationId()).processId(feedback.getProcessId()) | ||
| 55 | + .feedbackId(feedback.getId()).consumeDate(LocalDateTime.now()) | ||
| 56 | + .status(MesWmItemConsumeStatusEnum.PREPARE.getStatus()).build(); | ||
| 57 | + itemConsumeMapper.insert(consume); | ||
| 58 | + // 2.2 批量生成消耗行(消耗数量 = BOM 用料比例 × 报工数量) | ||
| 59 | + List<MesWmItemConsumeLineDO> lines = convertList(boms, bom -> MesWmItemConsumeLineDO.builder() | ||
| 60 | + .consumeId(consume.getId()).itemId(bom.getItemId()) | ||
| 61 | + .quantity(bom.getQuantity().multiply(feedback.getFeedbackQuantity())).build()); | ||
| 62 | + itemConsumeLineService.createItemConsumeLineBatch(lines); | ||
| 63 | + return consume; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + @Override | ||
| 67 | + public void finishItemConsume(Long consumeId) { | ||
| 68 | + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后实现库存扣减 | ||
| 69 | + // List<MesWmItemConsumeLineDO> lines = itemConsumeLineService.getItemConsumeLineListByConsumeId(consumeId); | ||
| 70 | + // for (MesWmItemConsumeLineDO line : lines) { | ||
| 71 | + // materialStockService.decreaseStock(line.getItemId(), ..., line.getQuantity()); | ||
| 72 | + // } | ||
| 73 | + // 更新消耗单状态为已完成 | ||
| 74 | + itemConsumeMapper.updateById(MesWmItemConsumeDO.builder() | ||
| 75 | + .id(consumeId).status(MesWmItemConsumeStatusEnum.FINISHED.getStatus()).build()); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | +} |