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 1ecdc1dbc..338090113 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 @@ -705,12 +705,19 @@ public class PlanController { return success(true); } - @GetMapping("/line-change-record/list") - @Operation(summary = "获得生产计划换线记录列表") - @Parameter(name = "planId", description = "生产计划 ID", required = true, example = "1024") + @PutMapping("/change-line-batch") + @Operation(summary = "生产计划批量换线") + @PreAuthorize("@ss.hasPermission('mes:plan:update')") + public CommonResult changeLineBatch(@Valid @RequestBody PlanLineChangeBatchReqVO reqVO) { + planService.changeLineBatch(reqVO); + return success(true); + } + + @GetMapping("/line-change-record/page") + @Operation(summary = "获得生产计划换线记录分页") @PreAuthorize("@ss.hasPermission('mes:plan:query')") - public CommonResult> getLineChangeRecordList(@RequestParam("planId") Long planId) { - return success(planService.getLineChangeRecordList(planId)); + public CommonResult> getLineChangeRecordPage(@Valid PlanLineChangeRecordPageReqVO pageReqVO) { + return success(planService.getLineChangeRecordPage(pageReqVO)); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeBatchReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeBatchReqVO.java new file mode 100644 index 000000000..d95b8fa18 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeBatchReqVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.mes.controller.admin.plan.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 生产计划批量换线 Request VO") +@Data +public class PlanLineChangeBatchReqVO { + + @Schema(description = "生产计划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "生产计划 ID 不能为空") + private Long planId; + + @Valid + @NotEmpty(message = "换线明细列表不能为空") + @Schema(description = "换线明细列表", implementation = LineChangeItem.class) + private List items; + + @Schema(description = "备注") + private String remark; + + @Data + @Schema(description = "生产计划批量换线明细") + public static class LineChangeItem { + + @Schema(description = "计划工艺流程明细 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "计划工艺流程明细 ID 不能为空") + private Long planProcessRouteItemId; + + @Schema(description = "换线后的设备 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @NotNull(message = "换线后的设备 ID 不能为空") + private Long deviceId; + + @Schema(description = "备注") + private String remark; + + } + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordBatchRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordBatchRespVO.java new file mode 100644 index 000000000..db598c937 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordBatchRespVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.mes.controller.admin.plan.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 生产计划换线记录批次 Response VO") +@Data +public class PlanLineChangeRecordBatchRespVO { + + @Schema(description = "换线批次号", example = "B20260706000001") + private String changeBatchNo; + + @Schema(description = "生产计划编号", example = "1") + private Long planId; + + @Schema(description = "换线时间") + private LocalDateTime changeTime; + + @Schema(description = "操作人 ID", example = "1") + private Long operatorUserId; + + @Schema(description = "当前计划合格数量", example = "100") + private Long passNumber; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "变更工序数量", example = "2") + private Integer changeCount; + + @Schema(description = "换线明细列表") + private List items; + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordPageReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordPageReqVO.java new file mode 100644 index 000000000..4ed6fe10a --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordPageReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.mes.controller.admin.plan.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 生产计划换线记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PlanLineChangeRecordPageReqVO extends PageParam { + + @Schema(description = "生产计划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "生产计划 ID 不能为空") + private Long planId; + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordRespVO.java index 9c589333c..8cb73b6a7 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordRespVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanLineChangeRecordRespVO.java @@ -15,6 +15,9 @@ public class PlanLineChangeRecordRespVO { @Schema(description = "生产计划编号", example = "1") private Long planId; + @Schema(description = "换线批次号", example = "B202607060001") + private String changeBatchNo; + @Schema(description = "计划工艺流程明细编号", example = "1") private Long planProcessRouteItemId; diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanStatusEnum.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanStatusEnum.java index 97d3de60a..b16643deb 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanStatusEnum.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanStatusEnum.java @@ -11,11 +11,14 @@ public enum PlanStatusEnum { 已排产(1), 量产(2), 暂停(3), - 完工(4), + + //旧完工-启用 +// 完工(4), 已入库(5), 试产 (6), 待入库(7), - 已开工(8); + 已开工(8), + 完工(9); private final int value; diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/planlinechange/PlanLineChangeRecordDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/planlinechange/PlanLineChangeRecordDO.java index a1c5e6b85..77ba028ad 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/planlinechange/PlanLineChangeRecordDO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/planlinechange/PlanLineChangeRecordDO.java @@ -30,6 +30,10 @@ public class PlanLineChangeRecordDO extends BaseDO { * 生产计划编号 */ private Long planId; + /** + * 换线批次号 + */ + private String changeBatchNo; /** * 计划工艺流程明细编号 */ diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/planlinechange/PlanLineChangeRecordMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/planlinechange/PlanLineChangeRecordMapper.java index f3abe184d..b2e162b62 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/planlinechange/PlanLineChangeRecordMapper.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/planlinechange/PlanLineChangeRecordMapper.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.mes.dal.mysql.planlinechange; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanLineChangeRecordPageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.planlinechange.PlanLineChangeRecordDO; import org.apache.ibatis.annotations.Mapper; @@ -17,4 +19,11 @@ public interface PlanLineChangeRecordMapper extends BaseMapperX selectPage(PlanLineChangeRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eq(PlanLineChangeRecordDO::getPlanId, reqVO.getPlanId()) + .orderByDesc(PlanLineChangeRecordDO::getChangeTime) + .orderByDesc(PlanLineChangeRecordDO::getId)); + } + } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/no/MesNoRedisDAO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/no/MesNoRedisDAO.java index d97cd669d..55dd6433f 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/no/MesNoRedisDAO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/no/MesNoRedisDAO.java @@ -64,6 +64,10 @@ public class MesNoRedisDAO { * 生产报工 */ public static final String REPORT_NO_PREFIX = "WR-"; + /** + * 生产计划换线批次号 + */ + public static final String PLAN_LINE_CHANGE_BATCH_NO_PREFIX = "B"; /** * 能源设备 */ diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java index 18e4258c7..268277670 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java @@ -115,9 +115,11 @@ public interface PlanService { PageResult getPlanProductCapacityPage(PlanProductCapacityPageReqVO reqVO); - void changeLine(@Valid PlanLineChangeReqVO reqVO); + void changeLine(@Valid PlanLineChangeReqVO reqVO); - List getLineChangeRecordList(Long planId); + void changeLineBatch(@Valid PlanLineChangeBatchReqVO reqVO); + + PageResult getLineChangeRecordPage(PlanLineChangeRecordPageReqVO pageReqVO); } 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 201f5f9ed..e7d971f13 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 @@ -989,35 +989,105 @@ public class PlanServiceImpl implements PlanService { if (plan == null) { throw exception(PLAN_NOT_EXISTS); } - PlanProcessRouteItemDO planRouteItem = planProcessRouteItemMapper.selectById(reqVO.getPlanProcessRouteItemId()); - if (planRouteItem == null || !Objects.equals(planRouteItem.getPlanId(), reqVO.getPlanId())) { + String changeBatchNo = noRedisDAO.generate6(MesNoRedisDAO.PLAN_LINE_CHANGE_BATCH_NO_PREFIX); + changeLineItem(plan, reqVO.getPlanProcessRouteItemId(), reqVO.getDeviceId(), reqVO.getRemark(), changeBatchNo, + LocalDateTime.now(), getLoginUserId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void changeLineBatch(PlanLineChangeBatchReqVO reqVO) { + PlanDO plan = planMapper.selectById(reqVO.getPlanId()); + if (plan == null) { throw exception(PLAN_NOT_EXISTS); } - DeviceLedgerDO afterDevice = deviceLedgerMapper.selectById(reqVO.getDeviceId()); + String changeBatchNo = null; + LocalDateTime changeTime = LocalDateTime.now(); + Long operatorUserId = getLoginUserId(); + for (PlanLineChangeBatchReqVO.LineChangeItem item : reqVO.getItems()) { + PlanProcessRouteItemDO planRouteItem = planProcessRouteItemMapper.selectById(item.getPlanProcessRouteItemId()); + if (planRouteItem == null || !Objects.equals(planRouteItem.getPlanId(), plan.getId())) { + throw exception(PLAN_NOT_EXISTS); + } + if (Objects.equals(planRouteItem.getDeviceId(), item.getDeviceId())) { + continue; + } + if (changeBatchNo == null) { + changeBatchNo = noRedisDAO.generate6(MesNoRedisDAO.PLAN_LINE_CHANGE_BATCH_NO_PREFIX); + } + String remark = item.getRemark() != null ? item.getRemark() : reqVO.getRemark(); + changeLineItem(plan, planRouteItem, item.getDeviceId(), remark, changeBatchNo, + changeTime, operatorUserId); + } + } + + private void changeLineItem(PlanDO plan, Long planProcessRouteItemId, Long deviceId, String remark, + String changeBatchNo, LocalDateTime changeTime, Long operatorUserId) { + PlanProcessRouteItemDO planRouteItem = planProcessRouteItemMapper.selectById(planProcessRouteItemId); + if (planRouteItem == null || !Objects.equals(planRouteItem.getPlanId(), plan.getId())) { + throw exception(PLAN_NOT_EXISTS); + } + changeLineItem(plan, planRouteItem, deviceId, remark, changeBatchNo, changeTime, operatorUserId); + } + + private void changeLineItem(PlanDO plan, PlanProcessRouteItemDO planRouteItem, Long deviceId, String remark, + String changeBatchNo, LocalDateTime changeTime, Long operatorUserId) { + DeviceLedgerDO afterDevice = deviceLedgerMapper.selectById(deviceId); PlanLineChangeRecordDO record = new PlanLineChangeRecordDO(); record.setPlanId(plan.getId()); + record.setChangeBatchNo(changeBatchNo); record.setPlanProcessRouteItemId(planRouteItem.getId()); record.setProcessParameterId(planRouteItem.getProcessParameterId()); record.setProcessParameterName(planRouteItem.getProcessParameterName()); record.setBeforeDeviceId(planRouteItem.getDeviceId()); record.setBeforeDeviceName(planRouteItem.getDeviceName()); - record.setAfterDeviceId(reqVO.getDeviceId()); + record.setAfterDeviceId(deviceId); record.setAfterDeviceName(afterDevice == null ? null : afterDevice.getDeviceName()); - record.setChangeTime(LocalDateTime.now()); - record.setOperatorUserId(getLoginUserId()); + record.setChangeTime(changeTime); + record.setOperatorUserId(operatorUserId); record.setPassNumber(plan.getPassNumber()); - record.setRemark(reqVO.getRemark()); + record.setRemark(remark); planLineChangeRecordMapper.insert(record); - planRouteItem.setDeviceId(reqVO.getDeviceId()); + planRouteItem.setDeviceId(deviceId); planRouteItem.setDeviceName(afterDevice == null ? null : afterDevice.getDeviceName()); planProcessRouteItemMapper.updateById(planRouteItem); } @Override - public List getLineChangeRecordList(Long planId) { - return BeanUtils.toBean(planLineChangeRecordMapper.selectListByPlanId(planId), PlanLineChangeRecordRespVO.class); + public PageResult getLineChangeRecordPage(PlanLineChangeRecordPageReqVO pageReqVO) { + List records = planLineChangeRecordMapper.selectListByPlanId(pageReqVO.getPlanId()); + if (CollUtil.isEmpty(records)) { + return new PageResult<>(Collections.emptyList(), 0L); + } + Map> batchMap = records.stream() + .collect(Collectors.groupingBy(this::getLineChangeBatchKey, LinkedHashMap::new, Collectors.toList())); + List batchList = batchMap.entrySet().stream() + .map(entry -> buildLineChangeBatchRespVO(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); + int fromIndex = Math.min((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), batchList.size()); + int toIndex = Math.min(fromIndex + pageReqVO.getPageSize(), batchList.size()); + return new PageResult<>(batchList.subList(fromIndex, toIndex), (long) batchList.size()); + } + + private String getLineChangeBatchKey(PlanLineChangeRecordDO record) { + return StringUtils.isNotBlank(record.getChangeBatchNo()) ? record.getChangeBatchNo() : String.valueOf(record.getId()); + } + + private PlanLineChangeRecordBatchRespVO buildLineChangeBatchRespVO(String changeBatchNo, + List records) { + PlanLineChangeRecordDO firstRecord = records.get(0); + PlanLineChangeRecordBatchRespVO respVO = new PlanLineChangeRecordBatchRespVO(); + respVO.setChangeBatchNo(changeBatchNo); + respVO.setPlanId(firstRecord.getPlanId()); + respVO.setChangeTime(firstRecord.getChangeTime()); + respVO.setOperatorUserId(firstRecord.getOperatorUserId()); + respVO.setPassNumber(firstRecord.getPassNumber()); + respVO.setRemark(firstRecord.getRemark()); + respVO.setChangeCount(records.size()); + respVO.setItems(BeanUtils.toBean(records, PlanLineChangeRecordRespVO.class)); + return respVO; }