From c6c77294af79b6badc5f871b5cd60a27a2fec69a Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 10 Jul 2026 11:15:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(schProdScheduleItem):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E4=B8=8B=E5=8F=91=E5=8A=9F=E8=83=BD=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=90=E6=9D=A1=E6=98=8E=E7=BB=86=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E4=B8=8B=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ISchProdScheduleItemService 中新增 receiveFromDetail 方法接口 - 在 SchProdScheduleItemController 中新增 /receiveFromDetail 接口 - 在 SchProdScheduleItemServiceImpl 中实现明细下发业务逻辑 - 新增 SchProdScheduleItemDispatchBo 数据传输对象 - 支持按明细+工序步骤维度删除重复记录后再重新插入 - 使用明细自身 scheduleDate 作为生产日期确保多天排产准确性 - 实现批量插入排产单明细项功能 --- .../SchProdScheduleItemController.java | 13 +++ .../bo/SchProdScheduleItemDispatchBo.java | 69 +++++++++++++ .../service/ISchProdScheduleItemService.java | 8 ++ .../impl/SchProdScheduleItemServiceImpl.java | 98 +++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemDispatchBo.java diff --git a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java index 9b87bdf57..84655b4af 100644 --- a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java +++ b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java @@ -24,6 +24,7 @@ import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.flow.domain.bo.SchProdScheduleItemReceiveBo; import com.klp.flow.domain.bo.SchProdScheduleItemMergeValidateBo; import com.klp.flow.domain.bo.SchProdScheduleItemSortBo; +import com.klp.flow.domain.bo.SchProdScheduleItemDispatchBo; import com.klp.flow.service.ISchProdScheduleItemService; import com.klp.common.core.page.TableDataInfo; @@ -132,6 +133,18 @@ public class SchProdScheduleItemController extends BaseController { return toAjax(iSchProdScheduleItemService.receiveByBo(receiveBo)); } + /** + * 明细下发:逐条从 sch_prod_schedule_detail 下发到 sch_prod_schedule_item + * 生产日期使用明细的 scheduleDate,支持一条一条明细独立下发 + * 若已下发过(同明细+同工序),先删除旧记录再重新插入 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/receiveFromDetail") + public R receiveFromDetail(@Validated @RequestBody SchProdScheduleItemDispatchBo dispatchBo) { + return toAjax(iSchProdScheduleItemService.receiveFromDetail(dispatchBo)); + } + /** * 合并校验:检查待合并记录来源产需单的 header 字段是否一致 */ diff --git a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemDispatchBo.java b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemDispatchBo.java new file mode 100644 index 000000000..26c174033 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemDispatchBo.java @@ -0,0 +1,69 @@ +package com.klp.flow.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 排产明细下发请求对象 —— 从 sch_prod_schedule_detail 逐条下发到 sch_prod_schedule_item + * + * @author klp + * @date 2026-07-10 + */ +@Data +public class SchProdScheduleItemDispatchBo { + + /** + * 明细下发配置列表(每条明细独立下发,各自携带工序步骤) + */ + @NotEmpty(message = "明细下发配置不能为空") + private List detailList; + + /** + * 单条明细的下发配置 + */ + @Data + public static class DetailDispatchConfig { + /** + * 排产明细ID(sch_prod_schedule_detail.schedule_detail_id) + */ + @NotNull(message = "明细ID不能为空") + private Long scheduleDetailId; + + /** + * 工序ID(sch_prod_process.process_id),用于区分下发后按工序分组 + */ + @NotNull(message = "工序ID不能为空") + private Long processId; + + /** + * 工序步骤列表 + */ + @NotEmpty(message = "工序步骤不能为空") + private List stepList; + } + + /** + * 工序步骤配置 + */ + @Data + public static class StepConfig { + /** + * 步骤ID(sch_prod_process_step.step_id,下发后存为 actionId) + */ + @NotNull(message = "步骤ID不能为空") + private Long stepId; + + /** + * 步骤顺序号 + */ + private Long stepOrder; + + /** + * 步骤名称 + */ + private String stepName; + } +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java index 4a47d5c03..54111ec84 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java +++ b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java @@ -8,6 +8,7 @@ import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.flow.domain.bo.SchProdScheduleItemReceiveBo; import com.klp.flow.domain.bo.SchProdScheduleItemMergeValidateBo; import com.klp.flow.domain.bo.SchProdScheduleItemSortBo; +import com.klp.flow.domain.bo.SchProdScheduleItemDispatchBo; import com.klp.common.core.page.TableDataInfo; import com.klp.common.core.domain.PageQuery; @@ -76,4 +77,11 @@ public interface ISchProdScheduleItemService { * 保存已排产拖拽排序 */ Boolean saveSort(SchProdScheduleItemSortBo sortBo); + + /** + * 明细下发:逐条从 sch_prod_schedule_detail 下发到 sch_prod_schedule_item + * 若已下发过(同明细+同工序),先删除再重新插入 + * 生产日期使用明细自身的 scheduleDate,而非主表的 prodDate + */ + Boolean receiveFromDetail(SchProdScheduleItemDispatchBo dispatchBo); } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java index 80076d069..26bf35c2a 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java @@ -14,6 +14,7 @@ import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.flow.domain.bo.SchProdScheduleItemReceiveBo; import com.klp.flow.domain.bo.SchProdScheduleItemMergeValidateBo; import com.klp.flow.domain.bo.SchProdScheduleItemSortBo; +import com.klp.flow.domain.bo.SchProdScheduleItemDispatchBo; import com.klp.flow.domain.vo.SchProdScheduleItemVo; import com.klp.flow.domain.vo.SchProdScheduleItemMergeValidateVo; import com.klp.flow.domain.SchProdScheduleItem; @@ -480,6 +481,103 @@ public class SchProdScheduleItemServiceImpl implements ISchProdScheduleItemServi return true; } + /** + * 明细下发:逐条从 sch_prod_schedule_detail 下发到 sch_prod_schedule_item + * 若已下发过(同明细+同工序步骤),先删除再重新插入,避免重复 + * 生产日期使用明细自身的 scheduleDate,保证多天排产的时间准确性 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean receiveFromDetail(SchProdScheduleItemDispatchBo dispatchBo) { + List detailList = dispatchBo.getDetailList(); + + for (SchProdScheduleItemDispatchBo.DetailDispatchConfig config : detailList) { + Long detailId = config.getScheduleDetailId(); + + // 1. 查询排产明细 + SchProdScheduleDetail detail = schProdScheduleDetailMapper.selectById(detailId); + if (detail == null) { + throw new RuntimeException("排产明细不存在,scheduleDetailId=" + detailId); + } + + // 2. 查询产需单主表 + SchProdSchedule header = schProdScheduleMapper.selectById(detail.getScheduleId()); + if (header == null) { + throw new RuntimeException("产需单不存在,scheduleId=" + detail.getScheduleId()); + } + + // 3. 收集本次下发的步骤ID列表 + List stepIds = config.getStepList().stream() + .map(SchProdScheduleItemDispatchBo.StepConfig::getStepId) + .collect(Collectors.toList()); + + // 4. 删除该明细上一次下发的内容(同明细 + 同工序步骤),区分工序避免误删 + baseMapper.delete( + Wrappers.lambdaQuery() + .eq(SchProdScheduleItem::getScheduleDetailIds, String.valueOf(detailId)) + .in(SchProdScheduleItem::getActionId, stepIds) + ); + + // 5. 根据工序步骤逐条生成新的排产单明细项 + List addList = new ArrayList<>(); + for (SchProdScheduleItemDispatchBo.StepConfig step : config.getStepList()) { + SchProdScheduleItem item = new SchProdScheduleItem(); + + // —— 从 header 复制主表字段 —— + item.setScheduleNo(header.getScheduleNo()); + item.setScheduleStatus(2L); // 已下达 + item.setTotalPlanWeight(header.getTotalPlanWeight()); + item.setRelContractNo(header.getRelContractNo()); + item.setBusinessUser(header.getBusinessUser()); + item.setBusinessPhone(header.getBusinessPhone()); + item.setOrderDate(header.getOrderDate()); + item.setCustomerName(header.getCustomerName()); + item.setDeliveryCycle(header.getDeliveryCycle()); + item.setUsePurpose(header.getUsePurpose()); + item.setProductType(header.getProductType()); + item.setThicknessTolerance(header.getThicknessTolerance()); + item.setWidthTolerance(header.getWidthTolerance()); + item.setSurfaceQuality(header.getSurfaceQuality()); + item.setSurfaceTreatment(header.getSurfaceTreatment()); + item.setInnerDiameter(header.getInnerDiameter()); + item.setOuterDiameter(header.getOuterDiameter()); + item.setPackReq(header.getPackReq()); + item.setCutEdgeReq(header.getCutEdgeReq()); + item.setSingleCoilWeight(header.getSingleCoilWeight()); + item.setWeightDeviation(header.getWeightDeviation()); + item.setOtherTechReq(header.getOtherTechReq()); + item.setPaymentDesc(header.getPaymentDesc()); + item.setRemark(header.getRemark()); + + // —— 生产日期使用明细自身的 scheduleDate,实现逐条明细独立时间 —— + item.setProdDate(detail.getScheduleDate()); + + // —— 从 detail 复制明细字段 —— + item.setSpec(detail.getSpec()); + item.setMaterial(detail.getMaterial()); + item.setScheduleWeight(detail.getScheduleWeight()); + item.setProductItem(detail.getProductType()); + item.setRowRemark(detail.getRemark()); + + // —— 工序步骤 —— + item.setActionId(step.getStepId()); + + // —— 来源追溯(未合并,存单明细ID) —— + item.setScheduleDetailIds(String.valueOf(detailId)); + + validEntityBeforeSave(item); + addList.add(item); + } + + // 6. 批量插入新记录 + if (!addList.isEmpty()) { + baseMapper.insertBatch(addList); + } + } + + return true; + } + /** * 合并校验:检查待合并记录来源产需单的 header 字段是否一致 */