diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/PlanController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/PlanController.java index 000ea5608..cd7a6290c 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/PlanController.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/PlanController.java @@ -19,12 +19,15 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; import cn.iocoder.yudao.module.iot.framework.mqtt.utils.DateUtils; import cn.iocoder.yudao.module.mes.controller.admin.itemrequisition.vo.ItemRequisitionSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.*; +import cn.iocoder.yudao.module.mes.controller.admin.task.vo.TaskStatusEnum; import cn.iocoder.yudao.module.mes.controller.admin.zjproductrecord.vo.ZjProductRecordSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.bom.BomDO; import cn.iocoder.yudao.module.mes.dal.dataobject.bom.BomDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjproduct.ZjProductDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjproductrecord.ZjProductRecordDO; import cn.iocoder.yudao.module.mes.dal.mysql.bom.BomDetailMapper; @@ -37,6 +40,7 @@ import cn.iocoder.yudao.module.mes.service.itemrequisition.ItemAnalysisService; import cn.iocoder.yudao.module.mes.service.itemrequisition.entity.ItemRequisitionAndStock; import cn.iocoder.yudao.module.mes.service.organization.OrganizationService; import cn.iocoder.yudao.module.mes.service.plan.PlanService; +import cn.iocoder.yudao.module.mes.service.task.TaskService; import cn.iocoder.yudao.module.mes.service.zjproduct.ZjProductService; import cn.iocoder.yudao.module.mes.service.zjproductrecord.ZjProductRecordService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -100,6 +104,8 @@ public class PlanController { @Resource private BomDetailMapper bomDetailMapper; + @Resource + private TaskService taskService; @PostMapping("/create") @@ -307,9 +313,36 @@ public class PlanController { else if ("store".equals(statusUpdateVO.getCode())) { planDO.setStatus(PlanStatusEnum.已入库.getValue()); planService.createPlanStockIn(statusUpdateVO, planDO); + + TaskDO taskDO = taskService.getTask(planDO.getTaskId()); + if (taskDO != null) { + // 条件1:任务单已完成排产(按你的字段,通常 isScheduled == 1) + boolean scheduledFinished = Integer.valueOf(1).equals(taskDO.getIsScheduled()); + + // 条件2:任务单下所有计划都为入库 + List planList = planMapper.selectList( + Wrappers.lambdaQuery() + .eq(PlanDO::getTaskId, planDO.getTaskId()) + ); + boolean allPlanFinished = !planList.isEmpty() && planList.stream() + .allMatch(p -> Integer.valueOf(PlanStatusEnum.已入库.getValue()).equals(p.getStatus())); + + if (scheduledFinished && allPlanFinished) { + taskDO.setStatus(TaskStatusEnum.已完成.getValue()); // 10-已完成 + taskService.updateTask(taskDO); + } + } + } else if ("commence".equals(statusUpdateVO.getCode())) { planDO.setStatus(PlanStatusEnum.已开工.getValue()); + + // 修改任务单状态为生产中 + TaskDO taskDO = taskService.getTask(planDO.getTaskId()); + if (taskDO != null) { + taskDO.setStatus(TaskStatusEnum.生产中.getValue()); + taskService.updateTask(taskDO); + } } planMapper.updateById(planDO); return success(true); diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java index 752cd8099..81be94a3b 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java @@ -28,6 +28,10 @@ public class PlanRespVO { @ExcelProperty("产品") private String productName; + @ExcelProperty("产品编码") + private String productCode; + + @Schema(description = "任务单明细ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18938") @ExcelProperty("任务单明细ID") private Long taskDetailId; @@ -157,4 +161,5 @@ public class PlanRespVO { @Schema(description = "交货日期") private LocalDateTime deliveryDate; + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java index 39d9702d1..ed6a97df5 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.mes.controller.admin.task; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -7,11 +8,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanSaveReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum; import cn.iocoder.yudao.module.mes.controller.admin.task.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.ViewTaskProductSummary; +import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper; import cn.iocoder.yudao.module.mes.service.task.TaskService; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; @@ -26,8 +31,8 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -40,6 +45,8 @@ public class TaskController { @Resource private TaskService taskService; + @Resource + private PlanMapper planMapper; @PostMapping("/create") @Operation(summary = "创建生产任务单") @@ -108,9 +115,53 @@ public class TaskController { @PreAuthorize("@ss.hasPermission('mes:task:query')") public CommonResult> pagePlanTask(@Valid TaskPageReqVO pageReqVO) { PageResult pageResult = taskService.getTaskPage2(pageReqVO); - return success(BeanUtils.toBean(pageResult, TaskRespVO.class)); + PageResult respPage = BeanUtils.toBean(pageResult, TaskRespVO.class); + + if (CollUtil.isEmpty(respPage.getList())) { + return success(respPage); + } + + Set taskIds = respPage.getList().stream() + .map(TaskRespVO::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + Map storedPlanNumberMap = new HashMap<>(); + Map totalNumberMap = new HashMap<>(); + + if (CollUtil.isNotEmpty(taskIds)) { + // 1) 已入库计划数量总和 + List storedPlans = planMapper.selectList( + Wrappers.lambdaQuery() + .in(PlanDO::getTaskId, taskIds) + .eq(PlanDO::getStatus, PlanStatusEnum.已入库.getValue()) + .eq(PlanDO::getDeleted, false) + ); + storedPlanNumberMap = storedPlans.stream() + .collect(Collectors.groupingBy( + PlanDO::getTaskId, + Collectors.summingLong(p -> p.getPlanNumber() == null ? 0L : p.getPlanNumber()) + )); + + // 2) 任务明细总数量 + List detailList = taskService.getTaskDetailListByTaskIds(taskIds); + totalNumberMap = detailList.stream() + .collect(Collectors.groupingBy( + TaskDetailDO::getTaskId, + Collectors.summingLong(d -> d.getNumber() == null ? 0L : d.getNumber()) + )); + } + + for (TaskRespVO item : respPage.getList()) { + Long taskId = item.getId(); + item.setStoredPlanNumber(storedPlanNumberMap.getOrDefault(taskId, 0L)); + item.setTotalNumber(totalNumberMap.getOrDefault(taskId, 0L)); + } + + return success(respPage); } + @GetMapping("/page") @Operation(summary = "获得生产任务单分页") @PreAuthorize("@ss.hasPermission('mes:task:query')") diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskRespVO.java index 466c7ac84..35beb7949 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskRespVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskRespVO.java @@ -78,6 +78,8 @@ public class TaskRespVO { @ExcelProperty("未计划数量") private Long unPlanNumber; + @Schema(description = "已入库数量", example = "") + private Long storedPlanNumber; } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskStatusEnum.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskStatusEnum.java index 1e428c1ea..a0227730b 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskStatusEnum.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskStatusEnum.java @@ -16,7 +16,11 @@ public enum TaskStatusEnum { 已排产(3), 开工(4), 完工(5), - 入库(6); + 入库(6), + 部分排产(7), + 待生产(8), + 生产中(9), + 已完成(10); private final Integer value; @@ -37,6 +41,11 @@ public enum TaskStatusEnum { statusList.add(TaskStatusEnum.开工.getValue()); statusList.add(TaskStatusEnum.完工.getValue()); statusList.add(TaskStatusEnum.入库.getValue()); + statusList.add(TaskStatusEnum.部分排产.getValue()); + statusList.add(TaskStatusEnum.待生产.getValue()); + statusList.add(TaskStatusEnum.生产中.getValue()); + statusList.add(TaskStatusEnum.已完成.getValue()); + return statusList; } } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java index 5ef9aa5fc..2521ed6d0 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java @@ -123,12 +123,7 @@ public class PlanServiceImpl implements PlanService { String code = ""; if (StringUtils.isEmpty(plan.getCode())) { code = autoCodeUtil.genSerialCode("PLAN_CODE", null); - // 1.4 生成订单号,并校验唯一性 -// String no = noRedisDAO.generate3(MesNoRedisDAO.PLAN_NO_PREFIX); -// if (planMapper.selectByNo(no) != null) { -// throw exception(PLAN_NOT_EXISTS); -// } -// plan.setCode(no); + plan.setCode(code); } else { if (planMapper.selectByNo(plan.getCode()) != null) { @@ -200,15 +195,34 @@ public class PlanServiceImpl implements PlanService { .sum(); //完成则更新排产字段 - if (totalNeed > 0 && totalPlanned >= totalNeed) { - TaskDO task = taskService.getTask(plan.getTaskId()); - if (task != null) { - task.setIsScheduled(1); +// if (totalNeed > 0 && totalPlanned >= totalNeed) { +// TaskDO task = taskService.getTask(plan.getTaskId()); +// if (task != null) { +// task.setIsScheduled(1); +// taskService.updateTask(task); +// } +// } + + TaskDO task = taskService.getTask(plan.getTaskId()); + if (task != null) { + // 9-生产中:不改状态 + if (!TaskStatusEnum.生产中.getValue().equals(task.getStatus())) { + // 先默认改为 7-部分排产 + Integer newStatus = TaskStatusEnum.部分排产.getValue(); + + // 满足条件则改为 8-待生产 + if (totalNeed > 0 && totalPlanned >= totalNeed) { + newStatus = TaskStatusEnum.待生产.getValue(); + task.setIsScheduled(1); // 你原有逻辑保留 + } + + task.setStatus(newStatus); taskService.updateTask(task); } } + saveReqVO.setPlanId(plan.getId()); saveReqVO.setId(id); itemRequisitionService.updateItemRequisition(saveReqVO); @@ -246,7 +260,7 @@ public class PlanServiceImpl implements PlanService { stockIn.setInType("产品入库"); ErpStockInSaveReqVO.Item item = new ErpStockInSaveReqVO.Item(); // todo 修改仓库 - item.setWarehouseId(4L); + item.setWarehouseId(12L); item.setProductId(planDO.getProductId()); if (planDO.getPassNumber() == null) { planDO.setPassNumber(0L); @@ -296,6 +310,10 @@ public class PlanServiceImpl implements PlanService { if (planDO.getProductId() != null) { ErpProductDO product = productService.getProduct(planDO.getProductId()); planRespVO.setProductName(product == null ? null : product.getName()); + planRespVO.setProductCode(product == null ? null : product.getBarCode()); + } else { + planRespVO.setProductName(null); + planRespVO.setProductCode(null); } if (planDO.getTaskId() != null) { @@ -315,6 +333,13 @@ public class PlanServiceImpl implements PlanService { planRespVO.setFeedingPipelineName(organization == null ? null : organization.getName()); } + if (planDO.getDeviceId() != null) { + DeviceLedgerDO device = deviceLedgerMapper.selectById(planDO.getDeviceId()); + planRespVO.setDeviceName(device == null ? null : device.getDeviceName()); + } else { + planRespVO.setDeviceName(null); + } + return planRespVO; } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java index 7d46fb31e..a701a3a50 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java @@ -170,4 +170,8 @@ public interface TaskService { */ List oneClickSchedule(TaskOneClickScheduleReqVO reqVO); + List getTaskDetailListByTaskIds(Collection taskIds); + + + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java index aa8b1bb7d..7a92b939a 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java @@ -198,9 +198,25 @@ public class TaskServiceImpl implements TaskService { unplanNumber = 0L; } + List storedPlans = planMapper.selectList( + Wrappers.lambdaQuery() + .eq(PlanDO::getTaskId, task.getId()) + .eq(PlanDO::getStatus, PlanStatusEnum.已入库.getValue()) + .eq(PlanDO::getDeleted, false) + ); + long storedPlanNumber = storedPlans.stream() + .map(PlanDO::getPlanNumber) + .filter(Objects::nonNull) + .mapToLong(Long::longValue) + .sum(); + + + task.setTotalNumber(totalNumber); task.setPlanNumber(planNumber); task.setUnPlanNumber(unplanNumber); + task.setStoredPlanNumber(storedPlanNumber); + } return bean; @@ -884,4 +900,18 @@ public class TaskServiceImpl implements TaskService { Integer cnt = calHolidayMapper.countHolidayInRange(start, end); return cnt != null && cnt > 0; } + + + + @Override + public List getTaskDetailListByTaskIds(Collection taskIds) { + if (CollUtil.isEmpty(taskIds)) { + return Collections.emptyList(); + } + return taskDetailMapper.selectList( + Wrappers.lambdaQuery() + .in(TaskDetailDO::getTaskId, taskIds) + ); + } + } \ No newline at end of file