yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -15,15 +15,18 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
import cn.iocoder.yudao.module.mes.enums.pro.MesProTaskStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
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.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
@@ -70,6 +73,8 @@
    private MesProRouteProcessService routeProcessService;
    @Resource
    private MesProWorkOrderBomService workOrderBomService;
    @Resource
    private MesProWorkOrderProcessService workOrderProcessService;
    @Resource
    @Lazy // 避免循环依赖
    private MesProTaskService taskService;
@@ -215,6 +220,18 @@
                .setUncheckQuantity(BigDecimal.ZERO));
        // 6. 根据是否需要检验,决定产出和入库方式
        // 6.2 调整 只要审批成功直接更新
        // 关键工序:更新任务 + 工单的已生产数量;非关键工序:只更新任务的已生产数量(工单只看关键工序产出)
        if (keyFlag) {
            updateTaskAndWorkOrderByFeedback(feedback);
        } else {
            taskService.updateProducedQuantity(feedback.getTaskId(),
                    feedback.getFeedbackQuantity(),
                    ObjectUtil.defaultIfNull(feedback.getQualifiedQuantity(), BigDecimal.ZERO),
                    ObjectUtil.defaultIfNull(feedback.getUnqualifiedQuantity(), BigDecimal.ZERO));
                checkAndPublishProductionFinished(feedback.getWorkOrderId());
        }
        if (checkFlag) {
            // 6.1 需要检验:生成产出单(质量状态=待检验),更新报工状态为待检验,等质检完成回调后再入库
            // 完成时回调见:MesQcIpqcServiceImpl#finishIpqc → splitPendingAndFinishProduce + updateProFeedbackWhenIpqcFinish
@@ -226,16 +243,7 @@
            // 6.2 无需检验:生成产出单(按合格/不合格拆行),直接完成入库
            MesWmProductProduceDO produce = productProduceService.generateProductProduce(feedback, false, reqVO);
            productProduceService.finishProductProduce(produce.getId());
            // 关键工序:更新任务 + 工单的已生产数量;非关键工序:只更新任务的已生产数量(工单只看关键工序产出)
            if (keyFlag) {
                updateTaskAndWorkOrderByFeedback(feedback);
            } else {
                taskService.updateProducedQuantity(feedback.getTaskId(),
                        feedback.getFeedbackQuantity(),
                        ObjectUtil.defaultIfNull(feedback.getQualifiedQuantity(), BigDecimal.ZERO),
                        ObjectUtil.defaultIfNull(feedback.getUnqualifiedQuantity(), BigDecimal.ZERO));
                checkAndPublishProductionFinished(feedback.getWorkOrderId());
            }
        }
        return true; // 已完成
@@ -248,6 +256,7 @@
     *   <li>使用报工数量(feedbackQuantity),累加任务和工单的已生产数量</li>
     *   <li>使用产出单行按 qualityStatus 聚合的合格品/不合格品数量,累加任务的合格品/不合格品数量
     *       (不直接用 feedback 上的数量,确保质检回调场景下数量来源正确)</li>
     *      isPush 是否推送生产完成事件
     * </ul>
     *
     * @param feedback 报工单
@@ -269,15 +278,19 @@
        // 2. 更新任务的已生产/合格/不合格数量
        taskService.updateProducedQuantity(feedback.getTaskId(),
                feedback.getFeedbackQuantity(), qualifiedQty, unqualifiedQty);
        // 3. 更新工单的已生产数量
        // 3. 更新订单的已生产数量
        // 新增逻辑:只有在该笔订单最后一个工序才更新生产订单的已生产数量
        MesProWorkOrderProcessDO lastProcess = workOrderProcessService.getLastWorkOrderProcessByWorkOrderId(feedback.getWorkOrderId());
        if (lastProcess != null && ObjUtil.equal(lastProcess.getProcessId(), feedback.getProcessId())) {
        workOrderService.updateProducedQuantity(feedback.getWorkOrderId(),
                feedback.getFeedbackQuantity());
        // 4. 更新 MPS 的已生产数量(如果是销售订单来源)
        MesProMpsRespDTO mps = mpsApi.getMpsByWorkOrderId(feedback.getWorkOrderId());
        if (mps != null) {
            mpsApi.updateMpsProducedQuantity(mps.getId(), feedback.getFeedbackQuantity());
        }
        }
        // 5. 检查并发布生产完成事件
        checkAndPublishProductionFinished(feedback.getWorkOrderId());
@@ -342,6 +355,11 @@
        // 1. 校验任务存在且未终态
        MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
        // 校验停工状态不能报工
        if (!MesProTaskStatusEnum.canFeedback(task.getStatus())) {
            throw exception(PRO_FEEDBACK_CANNOT_CREATE_WHEN_PAUSED);
        }
        // 2. 从任务自动填充关联字段(前端无需传入,后端统一从任务获取)
        reqVO.setWorkOrderId(task.getWorkOrderId());
        reqVO.setRouteId(task.getRouteId());
@@ -380,6 +398,12 @@
    public MesProFeedbackQuickCreateRespVO quickCreateFeedback(MesProFeedbackQuickCreateReqVO reqVO) {
        // 1. 校验任务存在且非终态
        MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
        // 校验停工状态不能报工
        if (!MesProTaskStatusEnum.canFeedback(task.getStatus())) {
            throw exception(PRO_FEEDBACK_CANNOT_CREATE_WHEN_PAUSED);
        }
        // 2. 校验工艺路线工序配置
        MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
                task.getRouteId(), task.getProcessId());
@@ -486,7 +510,8 @@
        // 4. 更新任务/工单的已生产数量
        feedback.setQualifiedQuantity(qualifiedQty).setUnqualifiedQuantity(unqualifiedQty);
        updateTaskAndWorkOrderByFeedback(feedback);
        //5.检查并发布生产完成事件
        checkAndPublishProductionFinished(feedback.getWorkOrderId());
    }
    @Override