Commit 6c2da289a4727457a07f7e405f4d520eab2220e5
1 parent
d8488e83
feat(mes): 添加报工相关字段和简化选择组件,优化数据处理逻辑
Showing
10 changed files
with
64 additions
and
35 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/card/MesProCardController.java
| @@ -124,15 +124,17 @@ public class MesProCardController { | @@ -124,15 +124,17 @@ public class MesProCardController { | ||
| 124 | Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( | 124 | Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( |
| 125 | convertSet(list, MesProCardDO::getItemId)); | 125 | convertSet(list, MesProCardDO::getItemId)); |
| 126 | Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( | 126 | Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( |
| 127 | - convertSet(list, MesProCardDO::getUnitMeasureId)); | 127 | + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); |
| 128 | // 2. 拼接 VO | 128 | // 2. 拼接 VO |
| 129 | return BeanUtils.toBean(list, MesProCardRespVO.class, vo -> { | 129 | return BeanUtils.toBean(list, MesProCardRespVO.class, vo -> { |
| 130 | MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), workOrder -> | 130 | MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), workOrder -> |
| 131 | vo.setWorkOrderCode(workOrder.getCode()).setWorkOrderName(workOrder.getName())); | 131 | vo.setWorkOrderCode(workOrder.getCode()).setWorkOrderName(workOrder.getName())); |
| 132 | - MapUtils.findAndThen(itemMap, vo.getItemId(), item -> | ||
| 133 | - vo.setItemCode(item.getCode()).setItemName(item.getName())); | ||
| 134 | - MapUtils.findAndThen(unitMeasureMap, vo.getUnitMeasureId(), | ||
| 135 | - unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); | 132 | + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { |
| 133 | + vo.setItemCode(item.getCode()).setItemName(item.getName()) | ||
| 134 | + .setSpecification(item.getSpecification()).setUnitMeasureId(item.getUnitMeasureId()); | ||
| 135 | + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), | ||
| 136 | + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); | ||
| 137 | + }); | ||
| 136 | }); | 138 | }); |
| 137 | } | 139 | } |
| 138 | 140 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/card/MesProCardProcessController.java
| @@ -103,18 +103,8 @@ public class MesProCardProcessController { | @@ -103,18 +103,8 @@ public class MesProCardProcessController { | ||
| 103 | Map<Long, MesProProcessDO> processMap = CollectionUtils.convertMap( | 103 | Map<Long, MesProProcessDO> processMap = CollectionUtils.convertMap( |
| 104 | processService.getProcessList(new ArrayList<>(convertSet(list, MesProCardProcessDO::getProcessId))), | 104 | processService.getProcessList(new ArrayList<>(convertSet(list, MesProCardProcessDO::getProcessId))), |
| 105 | MesProProcessDO::getId); | 105 | MesProProcessDO::getId); |
| 106 | - // 工位:逐个获取(MesMdWorkstationService 暂无批量方法,单页数据量小可接受) | ||
| 107 | - // TODO @AI:还是批量,getWorkstationMap | ||
| 108 | - Set<Long> workstationIds = convertSet(list, MesProCardProcessDO::getWorkstationId); | ||
| 109 | - Map<Long, MesMdWorkstationDO> workstationMap = new HashMap<>(); | ||
| 110 | - workstationIds.forEach(wsId -> { | ||
| 111 | - if (wsId != null) { | ||
| 112 | - MesMdWorkstationDO ws = workstationService.getWorkstation(wsId); | ||
| 113 | - if (ws != null) { | ||
| 114 | - workstationMap.put(wsId, ws); | ||
| 115 | - } | ||
| 116 | - } | ||
| 117 | - }); | 106 | + Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap( |
| 107 | + convertSet(list, MesProCardProcessDO::getWorkstationId)); | ||
| 118 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( | 108 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| 119 | convertSet(list, MesProCardProcessDO::getUserId)); | 109 | convertSet(list, MesProCardProcessDO::getUserId)); |
| 120 | // 2. 拼接 VO | 110 | // 2. 拼接 VO |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java
| @@ -195,15 +195,14 @@ public class MesProFeedbackController { | @@ -195,15 +195,14 @@ public class MesProFeedbackController { | ||
| 195 | // 1.5 工序 | 195 | // 1.5 工序 |
| 196 | Map<Long, MesProProcessDO> processMap = processService.getProcessMap( | 196 | Map<Long, MesProProcessDO> processMap = processService.getProcessMap( |
| 197 | new ArrayList<>(convertSet(list, MesProFeedbackDO::getProcessId))); | 197 | new ArrayList<>(convertSet(list, MesProFeedbackDO::getProcessId))); |
| 198 | - // 1.6 工序的 checkFlag:批量查询后按 routeId 分组,再按 processId 建内层 Map | 198 | + // 1.6 工序的 checkFlag:批量查询后直接构建 routeId -> processId -> checkFlag 的双层 Map |
| 199 | List<MesProRouteProcessDO> allRouteProcesses = routeProcessService.getRouteProcessListByRouteIds(routeIds); | 199 | List<MesProRouteProcessDO> allRouteProcesses = routeProcessService.getRouteProcessListByRouteIds(routeIds); |
| 200 | - // TODO @AI:直接构建出 checkFlagMap,避免构建 routeProcessMultiMap 的中间结果,减少内存占用;另外,变量名字在想下; | ||
| 201 | - Map<Long, List<MesProRouteProcessDO>> routeProcessMultiMap = convertMultiMap(allRouteProcesses, | ||
| 202 | - MesProRouteProcessDO::getRouteId); | ||
| 203 | - Map<Long, Map<Long, Boolean>> checkFlagMap = new HashMap<>(); | ||
| 204 | - routeProcessMultiMap.forEach((routeId, rpList) -> | ||
| 205 | - checkFlagMap.put(routeId, convertMap(rpList, MesProRouteProcessDO::getProcessId, | ||
| 206 | - rp -> Boolean.TRUE.equals(rp.getCheckFlag())))); | 200 | + Map<Long, Map<Long, Boolean>> routeProcessCheckFlagMap = new HashMap<>(); |
| 201 | + for (MesProRouteProcessDO rp : allRouteProcesses) { | ||
| 202 | + routeProcessCheckFlagMap | ||
| 203 | + .computeIfAbsent(rp.getRouteId(), k -> new HashMap<>()) | ||
| 204 | + .put(rp.getProcessId(), Boolean.TRUE.equals(rp.getCheckFlag())); | ||
| 205 | + } | ||
| 207 | // 1.7 报工人/审核人 | 206 | // 1.7 报工人/审核人 |
| 208 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( | 207 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| 209 | convertSetByFlatMap(list, feedback -> | 208 | convertSetByFlatMap(list, feedback -> |
| @@ -221,7 +220,7 @@ public class MesProFeedbackController { | @@ -221,7 +220,7 @@ public class MesProFeedbackController { | ||
| 221 | findAndThen(processMap, vo.getProcessId(), process -> | 220 | findAndThen(processMap, vo.getProcessId(), process -> |
| 222 | vo.setProcessCode(process.getCode()).setProcessName(process.getName())); | 221 | vo.setProcessCode(process.getCode()).setProcessName(process.getName())); |
| 223 | // checkFlag | 222 | // checkFlag |
| 224 | - findAndThen(checkFlagMap, vo.getRouteId(), processCheckMap -> | 223 | + findAndThen(routeProcessCheckFlagMap, vo.getRouteId(), processCheckMap -> |
| 225 | findAndThen(processCheckMap, vo.getProcessId(), vo::setCheckFlag)); | 224 | findAndThen(processCheckMap, vo.getProcessId(), vo::setCheckFlag)); |
| 226 | // 工单 | 225 | // 工单 |
| 227 | findAndThen(workOrderMap, vo.getWorkOrderId(), wo -> | 226 | findAndThen(workOrderMap, vo.getWorkOrderId(), wo -> |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java
| @@ -33,4 +33,13 @@ public class MesProFeedbackPageReqVO extends PageParam { | @@ -33,4 +33,13 @@ public class MesProFeedbackPageReqVO extends PageParam { | ||
| 33 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 33 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 34 | private LocalDateTime[] feedbackTime; | 34 | private LocalDateTime[] feedbackTime; |
| 35 | 35 | ||
| 36 | + @Schema(description = "产品物料编号", example = "100") | ||
| 37 | + private Long itemId; | ||
| 38 | + | ||
| 39 | + @Schema(description = "报工人编号", example = "1") | ||
| 40 | + private Long feedbackUserId; | ||
| 41 | + | ||
| 42 | + @Schema(description = "记录人编号(创建人)", example = "1") | ||
| 43 | + private String creator; | ||
| 44 | + | ||
| 36 | } | 45 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkorderController.java
| @@ -36,6 +36,7 @@ import java.util.*; | @@ -36,6 +36,7 @@ import java.util.*; | ||
| 36 | 36 | ||
| 37 | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | 37 | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| 38 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 38 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 39 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 39 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 40 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 40 | 41 | ||
| 41 | @Tag(name = "管理后台 - MES 生产工单") | 42 | @Tag(name = "管理后台 - MES 生产工单") |
| @@ -103,6 +104,15 @@ public class MesProWorkOrderController { | @@ -103,6 +104,15 @@ public class MesProWorkOrderController { | ||
| 103 | return success(new PageResult<>(buildWorkOrderRespVOList(pageResult.getList()), pageResult.getTotal())); | 104 | return success(new PageResult<>(buildWorkOrderRespVOList(pageResult.getList()), pageResult.getTotal())); |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 107 | + @GetMapping("/simple-list") | ||
| 108 | + @Operation(summary = "获得生产工单精简列表", description = "主要用于前端的下拉选项") | ||
| 109 | + public CommonResult<List<MesProWorkOrderRespVO>> getWorkOrderSimpleList() { | ||
| 110 | + List<MesProWorkOrderDO> list = workOrderService.getWorkOrderSimpleList(); | ||
| 111 | + return success(convertList(list, wo -> new MesProWorkOrderRespVO() | ||
| 112 | + .setId(wo.getId()).setCode(wo.getCode()).setName(wo.getName()) | ||
| 113 | + .setStatus(wo.getStatus()))); | ||
| 114 | + } | ||
| 115 | + | ||
| 106 | @GetMapping("/export-excel") | 116 | @GetMapping("/export-excel") |
| 107 | @Operation(summary = "导出生产工单 Excel") | 117 | @Operation(summary = "导出生产工单 Excel") |
| 108 | @PreAuthorize("@ss.hasPermission('mes:pro-work-order:export')") | 118 | @PreAuthorize("@ss.hasPermission('mes:pro-work-order:export')") |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/feedback/MesProFeedbackDO.java
| @@ -47,9 +47,10 @@ public class MesProFeedbackDO extends BaseDO { | @@ -47,9 +47,10 @@ public class MesProFeedbackDO extends BaseDO { | ||
| 47 | * 枚举 {@link MesProFeedbackTypeEnum} | 47 | * 枚举 {@link MesProFeedbackTypeEnum} |
| 48 | */ | 48 | */ |
| 49 | private Integer type; | 49 | private Integer type; |
| 50 | - // TODO @AI:这里需要字典么? | ||
| 51 | /** | 50 | /** |
| 52 | * 报工途径 | 51 | * 报工途径 |
| 52 | + * | ||
| 53 | + * 字典类型 mes_pro_feedback_channel | ||
| 53 | */ | 54 | */ |
| 54 | private String channel; | 55 | private String channel; |
| 55 | /** | 56 | /** |
| @@ -137,13 +138,16 @@ public class MesProFeedbackDO extends BaseDO { | @@ -137,13 +138,16 @@ public class MesProFeedbackDO extends BaseDO { | ||
| 137 | * 其他废品数量 | 138 | * 其他废品数量 |
| 138 | */ | 139 | */ |
| 139 | private BigDecimal otherScrapQuantity; | 140 | private BigDecimal otherScrapQuantity; |
| 140 | - // TODO @AI:feedbackUserId、approveUserId 关联字段 | ||
| 141 | /** | 141 | /** |
| 142 | * 报工用户编号 | 142 | * 报工用户编号 |
| 143 | + * | ||
| 144 | + * 关联 AdminUserDO#getId() | ||
| 143 | */ | 145 | */ |
| 144 | private Long feedbackUserId; | 146 | private Long feedbackUserId; |
| 145 | /** | 147 | /** |
| 146 | * 审核用户编号 | 148 | * 审核用户编号 |
| 149 | + * | ||
| 150 | + * 关联 AdminUserDO#getId() | ||
| 147 | */ | 151 | */ |
| 148 | private Long approveUserId; | 152 | private Long approveUserId; |
| 149 | /** | 153 | /** |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackStatusEnum.java
| @@ -6,10 +6,16 @@ import lombok.Getter; | @@ -6,10 +6,16 @@ import lombok.Getter; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | -// TODO @AI:注释下,状态的流转,不要太复杂; | ||
| 10 | /** | 9 | /** |
| 11 | * MES 生产报工状态枚举 | 10 | * MES 生产报工状态枚举 |
| 12 | * | 11 | * |
| 12 | + * 状态流转: | ||
| 13 | + * 1. 创建 → 草稿(PREPARE) | ||
| 14 | + * 2. 草稿 → 提交 → 审批中(APPROVING) | ||
| 15 | + * 3. 审批中 → 驳回 → 草稿(PREPARE) | ||
| 16 | + * 4. 审批中 → 执行 → 待检验(UNCHECK)或已完成(FINISHED),取决于工序 checkFlag | ||
| 17 | + * 5. 草稿/审批中 → 取消 → 已取消(CANCELED) | ||
| 18 | + * | ||
| 13 | * @author 芋道源码 | 19 | * @author 芋道源码 |
| 14 | */ | 20 | */ |
| 15 | @Getter | 21 | @Getter |
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.collection.CollUtil; | ||
| 4 | import cn.hutool.core.util.BooleanUtil; | 3 | import cn.hutool.core.util.BooleanUtil; |
| 5 | import cn.hutool.core.util.ObjUtil; | 4 | import cn.hutool.core.util.ObjUtil; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| @@ -20,7 +19,6 @@ import org.springframework.transaction.annotation.Transactional; | @@ -20,7 +19,6 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 20 | import org.springframework.validation.annotation.Validated; | 19 | import org.springframework.validation.annotation.Validated; |
| 21 | 20 | ||
| 22 | import java.time.LocalDateTime; | 21 | import java.time.LocalDateTime; |
| 23 | -import java.util.List; | ||
| 24 | 22 | ||
| 25 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 26 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 24 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| @@ -182,10 +180,7 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -182,10 +180,7 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 182 | * @return 是否需要检验 | 180 | * @return 是否需要检验 |
| 183 | */ | 181 | */ |
| 184 | private boolean getCheckFlag(Long routeId, Long processId) { | 182 | private boolean getCheckFlag(Long routeId, Long processId) { |
| 185 | - // TODO @AI:是不是 routeProcessService 提供一个查询 routeeProcess 的方法更好?目前只能查询 routeProcesses 全列表,效率较低 | ||
| 186 | - List<MesProRouteProcessDO> routeProcesses = routeProcessService.getRouteProcessListByRouteId(routeId); | ||
| 187 | - MesProRouteProcessDO routeProcess = CollUtil.findOne(routeProcesses, | ||
| 188 | - rp -> ObjUtil.equal(rp.getProcessId(), processId)); | 183 | + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId); |
| 189 | return routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); | 184 | return routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); |
| 190 | } | 185 | } |
| 191 | 186 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessService.java
| @@ -48,6 +48,15 @@ public interface MesProRouteProcessService { | @@ -48,6 +48,15 @@ public interface MesProRouteProcessService { | ||
| 48 | List<MesProRouteProcessDO> getRouteProcessListByRouteIds(Collection<Long> routeIds); | 48 | List<MesProRouteProcessDO> getRouteProcessListByRouteIds(Collection<Long> routeIds); |
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | + * 按工艺路线和工序获得工艺路线工序 | ||
| 52 | + * | ||
| 53 | + * @param routeId 工艺路线编号 | ||
| 54 | + * @param processId 工序编号 | ||
| 55 | + * @return 工艺路线工序 | ||
| 56 | + */ | ||
| 57 | + MesProRouteProcessDO getRouteProcessByRouteIdAndProcessId(Long routeId, Long processId); | ||
| 58 | + | ||
| 59 | + /** | ||
| 51 | * 按工艺路线删除工序(级联删除使用) | 60 | * 按工艺路线删除工序(级联删除使用) |
| 52 | * | 61 | * |
| 53 | * @param routeId 工艺路线编号 | 62 | * @param routeId 工艺路线编号 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java
| @@ -179,6 +179,11 @@ public class MesProRouteProcessServiceImpl implements MesProRouteProcessService | @@ -179,6 +179,11 @@ public class MesProRouteProcessServiceImpl implements MesProRouteProcessService | ||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | @Override | 181 | @Override |
| 182 | + public MesProRouteProcessDO getRouteProcessByRouteIdAndProcessId(Long routeId, Long processId) { | ||
| 183 | + return routeProcessMapper.selectByRouteIdAndProcessId(routeId, processId); | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + @Override | ||
| 182 | public void deleteRouteProcessByRouteId(Long routeId) { | 187 | public void deleteRouteProcessByRouteId(Long routeId) { |
| 183 | routeProcessMapper.deleteByRouteId(routeId); | 188 | routeProcessMapper.deleteByRouteId(routeId); |
| 184 | } | 189 | } |