Merge remote-tracking branch 'origin/dev_business' into dev_business
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "mcpServers": { |
| | | "idea": { |
| | | "url": "http://127.0.0.1:64342/stream", |
| | | "type": "http" |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å·¥èºè·¯çº¿å·¥åºæ¥å£æ°å¢ææBOM - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - çäº§å·¥åæ°å¢/ç¼è¾é¡µï¼`src/views/mes/pro/workorder/detail.vue`ï¼ |
| | | - åç»ä»¶ `modules/process-list.vue`ï¼å·¥åºåè¡¨ï¼ |
| | | - åç»ä»¶ `modules/process-form.vue`ï¼å·¥åºæ°å¢/ç¼è¾å¼¹çªï¼ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. ç¨æ·æ°å»º/ç¼è¾å·¥å â éæ©äº§å â `process-list.vue` è°ç¨æ¥å£è·åå·¥åºå表 |
| | | 2. å·¥åºå表è¿åæ°æ®ä¸æ°å¢ `bomItems` åæ®µï¼å·¥åºæææç»ï¼ |
| | | 3. å·¥åºå±å¼è¡èªå¨å±ç¤ºæææç»ï¼æ éé¢å¤è¯·æ±ï¼ |
| | | 4. ä¿å工忶 `bomItems` éå·¥åºæ°æ®ä¸èµ·æäº¤ |
| | | |
| | | ## API |
| | | |
| | | ### æ¥å£è¯´æ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/pro/route-process/list-by-product?productId={productId}` | æäº§åè·åå·¥èºè·¯çº¿å·¥åºï¼å«ææBOMï¼ | |
| | | |
| | | ### ååºå段æ°å¢ |
| | | |
| | | `MesProRouteProcessRespVO` æ°å¢åæ®µï¼ |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | bomItems | ProcessBomItem[] | å·¥åºææBOMåè¡¨ï¼æ æææ¶ä¸ºç©ºæ°ç»æ null | |
| | | |
| | | ### ProcessBomItem ç»æ |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | itemId | Long | BOMç©æç¼å· | |
| | | | itemCode | String | BOMç©æç¼ç | |
| | | | itemName | String | BOMç©æåç§° | |
| | | | quantity | BigDecimal | ç¨ææ¯ä¾ | |
| | | | remark | String | 夿³¨ | |
| | | |
| | | ### ååºç¤ºä¾ |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": [ |
| | | { |
| | | "id": 1, |
| | | "routeId": 10, |
| | | "processId": 100, |
| | | "processCode": "P001", |
| | | "processName": "çæ¥", |
| | | "sort": 1, |
| | | "nextProcessId": 101, |
| | | "nextProcessName": "ç»è£
", |
| | | "linkType": 3, |
| | | "keyFlag": true, |
| | | "checkFlag": false, |
| | | "backflushFlag": true, |
| | | "outputItemId": 200, |
| | | "outputItemCode": "M200", |
| | | "outputItemName": "åæåA", |
| | | "bomItems": [ |
| | | { |
| | | "itemId": 1001, |
| | | "itemCode": "M001", |
| | | "itemName": "颿¿", |
| | | "quantity": 2.0, |
| | | "remark": "" |
| | | }, |
| | | { |
| | | "itemId": 1002, |
| | | "itemCode": "M002", |
| | | "itemName": "çæ¡", |
| | | "quantity": 0.5, |
| | | "remark": "" |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": 2, |
| | | "routeId": 10, |
| | | "processId": 101, |
| | | "processCode": "P002", |
| | | "processName": "ç»è£
", |
| | | "sort": 2, |
| | | "nextProcessId": null, |
| | | "bomItems": [] |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | bomItems | å·¥åºè¡¨æ ¼å±å¼è¡ | ç¹å»å±å¼æé®å以 Tag å表形å¼å±ç¤ºæ¯ä¸ªææç©æ | |
| | | | itemName / itemCode | Tag ææ¬ | ä¼å
æ¾ç¤ºç©æåç§°ï¼æ åç§°æ¶æ¾ç¤ºç¼ç | |
| | | | quantity | Tag åç¼ | æ¾ç¤ºä¸º `Ã{quantity}` æ ¼å¼ | |
| | | |
| | | ## å端对æ¥ç¡®è®¤æ¸
å |
| | | |
| | | ### å·²ä¿®æ¹æä»¶ï¼å½å忝已æï¼ |
| | | |
| | | | æä»¶ | ä¿®æ¹å
容 | |
| | | |------|----------| |
| | | | `src/api/mes/pro/route/process/index.ts` | `RouteProcess` æ¥å£æ°å¢ `bomItems?: ProcessBomItem[]` | |
| | | | `src/api/mes/pro/workorder/process/index.ts` | `WorkOrderProcess` æ¥å£æ°å¢ `bomItems?: ProcessBomItem[]` | |
| | | | `src/views/mes/pro/workorder/data.ts` | `useProcessGridColumns` æ°å¢å±å¼å `{ type: 'expand', width: 50 }` | |
| | | | `src/views/mes/pro/workorder/modules/process-list.vue` | `getList()` æ å° `bomItems`ï¼æ¨¡æ¿æ°å¢ `#expand` slot | |
| | | |
| | | ### é确认 |
| | | |
| | | 1. `ProcessBomItem` æ¥å£ç±»åå¨å端 API æä»¶ä¸å·²è¡¥å
ï¼ç¡®è®¤ä¸å端è¿åç»æä¸è´ |
| | | 2. å±å¼è¡å
çæææç» Tag å表å±ç¤ºæå½å设计ï¼èè² Tagï¼æ¾ç¤º `ç©æåç§° Ãç¨é` |
| | | 3. æ ææå·¥åºçå±å¼è¡ä¸ºç©ºï¼æ ä»»ä½å
容ï¼ï¼ä¸æ¾ç¤º"æææç»"æ é¢ |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | äº§åæªé
置工èºè·¯çº¿ | è¿å空å表ï¼ä¸æ¥é | |
| | | | å·¥èºè·¯çº¿æå·¥åºä½æªé
ç½®ææ | bomItems 为空ï¼å±å¼è¡æ å
容 | |
| | | | ææç©æå·²è¢«å é¤ | ä¸è¿åè¯¥æ¡ææè®°å½ï¼æ°æ®åºé»è¾å é¤ï¼ | |
| | | | å·¥åºè¢«å é¤åé建 | å±å¼è¡éæ°ä»æ¥å£è·åææ° BOM æ°æ® | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - åç«¯ç¡®ä¿æ ééå¯å³å¯éªè¯ï¼å¦ææ¥å£å·²ææ°æ®ï¼ï¼ä½¿ç¨å·²é
ç½®ææç产åIDè°ç¨æ¥å£ |
| | | - ææ BOM æ¥èª `mes_pro_route_product_bom` 表ï¼é
ç½®ææï¼ï¼ä¸æ¯äº§åæ å BOM |
| | | - BOM ç©æåç§°éè¿ `MesMdItemService` 宿¶æ¥è¯¢ï¼ç¡®ä¿å±ç¤ºææ°ç©æåç§° |
| | | - Mapper å±ä½¿ç¨ MyBatis-Plus `@TableLogic`ï¼å·²é»è¾å é¤çè®°å½ä¸ä¼è¿å |
| | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProProcessBomItemVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; |
| | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| | |
| | | return success(buildRouteProcessRespVO(routeProcess)); |
| | | } |
| | | |
| | | // TODO @èè¿ï¼å°åºå« list-by-item è¿æ¯ list-by-productï¼ |
| | | @GetMapping("/list-by-product") |
| | | @Operation(summary = "æäº§åè·å¾å·¥åºå表", description = "æ ¹æ®äº§åæ¥æ¾å
³èçå·¥èºè·¯çº¿ï¼è¿å该路线çå·¥åºå表") |
| | | @Operation(summary = "æäº§åè·å¾å·¥åºå表", description = "æ ¹æ®äº§åæ¥æ¾å
³èçå·¥èºè·¯çº¿ï¼è¿å该路线çå·¥åºå表ï¼å«åå·¥åºçææBOMï¼") |
| | | @Parameter(name = "productId", description = "产åç¼å·", required = true, example = "1") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") |
| | | public CommonResult<List<MesProRouteProcessRespVO>> getRouteProcessListByProduct(@RequestParam("productId") Long productId) { |
| | | List<MesProRouteProcessDO> list = routeProcessService.getRouteProcessListByProductId(productId); |
| | | return success(buildRouteProcessRespVOList(list)); |
| | | List<MesProRouteProcessRespVO> result = buildRouteProcessRespVOList(list); |
| | | |
| | | // æ¥è¯¢é
ç½®ææå¹¶æå·¥åºå¡«å
|
| | | Map<Long, List<MesProRouteProductBomDO>> bomByProcess = routeProcessService.getRouteProcessBomMapByProductId(productId); |
| | | if (!bomByProcess.isEmpty()) { |
| | | Set<Long> itemIds = bomByProcess.values().stream() |
| | | .flatMap(List::stream) |
| | | .map(MesProRouteProductBomDO::getItemId) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, MesMdItemDO> itemMap = mdItemService.getItemMap(itemIds); |
| | | for (MesProRouteProcessRespVO vo : result) { |
| | | List<MesProRouteProductBomDO> processBoms = bomByProcess.get(vo.getProcessId()); |
| | | if (CollUtil.isNotEmpty(processBoms)) { |
| | | vo.setBomItems(processBoms.stream().map(bom -> { |
| | | MesProProcessBomItemVO itemVO = new MesProProcessBomItemVO(); |
| | | itemVO.setItemId(bom.getItemId()); |
| | | itemVO.setQuantity(bom.getQuantity()); |
| | | itemVO.setRemark(bom.getRemark()); |
| | | MesMdItemDO item = itemMap.get(bom.getItemId()); |
| | | if (item != null) { |
| | | itemVO.setItemCode(item.getCode()); |
| | | itemVO.setItemName(item.getName()); |
| | | } |
| | | return itemVO; |
| | | }).collect(Collectors.toList())); |
| | | } |
| | | } |
| | | } |
| | | return success(result); |
| | | } |
| | | |
| | | @GetMapping("/list-by-route") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "å·¥åºææBOMæç» VO") |
| | | @Data |
| | | public class MesProProcessBomItemVO { |
| | | |
| | | @Schema(description = "BOMç©æç¼å·", example = "1001") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "BOMç©æç¼ç ", example = "M001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "BOMç©æåç§°", example = "ç©æA") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "ç¨ææ¯ä¾", example = "1.0") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES å·¥èºè·¯çº¿å·¥åº Response VO") |
| | | @Data |
| | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å·¥åºææBOMå表") |
| | | private List<MesProProcessBomItemVO> bomItems; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES ç产工åå·¥åºæ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class MesProWorkOrderProcessSaveReqVO { |
| | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å·¥åºææBOMå表") |
| | | private List<BomItem> bomItems; |
| | | |
| | | @Data |
| | | public static class BomItem { |
| | | |
| | | @Schema(description = "BOMç©æç¼å·", example = "1001") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "BOMç©æç¼ç ") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "BOMç©æåç§°") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "é¢è®¡ä½¿ç¨é") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; |
| | | 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.wm.itemconsume.MesWmItemConsumeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO; |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; |
| | | 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.route.MesProRouteProductBomService; |
| | | 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.MesProWorkOrderService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService; |
| | |
| | | @Resource |
| | | private MesProRouteProcessService routeProcessService; |
| | | @Resource |
| | | private MesProRouteProductBomService routeProductBomService; |
| | | private MesProWorkOrderBomService workOrderBomService; |
| | | @Resource |
| | | @Lazy // é¿å
循ç¯ä¾èµ |
| | | private MesProTaskService taskService; |
| | |
| | | boolean backflushFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getBackflushFlag()); |
| | | if (backflushFlag) { |
| | | // 3.1 æ ¡éªåå²å·¥åºå¿
é¡»é
ç½® BOM æ¶èï¼é¿å
éé»ä¸æ£æ |
| | | List<MesProRouteProductBomDO> boms = routeProductBomService.getRouteProductBomList( |
| | | feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId()); |
| | | List<MesProWorkOrderBomDO> boms = workOrderBomService.getWorkOrderBomListByWorkOrderId( |
| | | feedback.getWorkOrderId()); |
| | | if (CollUtil.isEmpty(boms)) { |
| | | throw exception(PRO_FEEDBACK_BACKFLUSH_BOM_REQUIRED); |
| | | } |
| | |
| | | List<MesProRouteProcessDO> getRouteProcessListByProductId(Long productId); |
| | | |
| | | /** |
| | | * æäº§åè·å¾å·¥åºææBOM Map |
| | | * |
| | | * key = å·¥åºIDï¼value = 该工åºä¸çææBOMæç»å表 |
| | | * |
| | | * @param productId 产åç¼å· |
| | | * @return å·¥åº -> ææBOM æ å°ï¼äº§åæ å·¥èºè·¯çº¿æ¶è¿å空Map |
| | | */ |
| | | java.util.Map<Long, java.util.List<cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO>> |
| | | getRouteProcessBomMapByProductId(Long productId); |
| | | |
| | | /** |
| | | * æå·¥åºè·å¾å·¥èºè·¯çº¿å·¥åºå表 |
| | | * |
| | | * @param processId å·¥åºç¼å· |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProcessMapper; |
| | | import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService; |
| | |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | @Resource |
| | | @Lazy |
| | | private MesProRouteService routeService; |
| | | @Resource |
| | | @Lazy |
| | | private MesProRouteProductBomService routeProductBomService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Map<Long, List<MesProRouteProductBomDO>> getRouteProcessBomMapByProductId(Long productId) { |
| | | MesProRouteProductDO routeProduct = routeProductService.getRouteProductByItemId(productId); |
| | | if (routeProduct == null) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | List<MesProRouteProductBomDO> bomList = routeProductBomService |
| | | .getRouteProductBomListByRouteIdAndProductId(routeProduct.getRouteId(), productId); |
| | | if (CollUtil.isEmpty(bomList)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | return bomList.stream().collect(Collectors.groupingBy(MesProRouteProductBomDO::getProcessId)); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesProRouteProcessDO> getRouteProcessListByProcessId(Long processId) { |
| | | return routeProcessMapper.selectListByProcessId(processId); |
| | | } |
| | |
| | | */ |
| | | void deleteRouteProductBomByRouteIdAndProductId(Long routeId, Long productId); |
| | | |
| | | /** |
| | | * æå·¥èºè·¯çº¿åäº§åæ¥è¯¢ BOM å表 |
| | | * |
| | | * @param routeId å·¥èºè·¯çº¿ç¼å· |
| | | * @param productId 产åç©æç¼å· |
| | | * @return BOM å表 |
| | | */ |
| | | List<MesProRouteProductBomDO> getRouteProductBomListByRouteIdAndProductId(Long routeId, Long productId); |
| | | |
| | | } |
| | |
| | | routeProductBomMapper.deleteByRouteIdAndProductId(routeId, productId); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesProRouteProductBomDO> getRouteProductBomListByRouteIdAndProductId(Long routeId, Long productId) { |
| | | return routeProductBomMapper.selectListByRouteIdAndProductId(routeId, productId); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.process.MesProWorkOrderProcessPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.process.MesProWorkOrderProcessSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.process.MesProWorkOrderProcessSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderBomMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderProcessMapper; |
| | | import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; |
| | |
| | | private MesProProcessService processService; |
| | | @Resource |
| | | private MesProRouteProcessService routeProcessService; |
| | | @Resource |
| | | @Lazy |
| | | private MesProWorkOrderBomService workOrderBomService; |
| | | @Resource |
| | | private MesProWorkOrderBomMapper workOrderBomMapper; |
| | | |
| | | @Override |
| | | public Long createWorkOrderProcess(MesProWorkOrderProcessSaveReqVO createReqVO) { |
| | |
| | | } |
| | | } |
| | | |
| | | // 4. é建工åºé¾ |
| | | // 4. ä¿åå·¥å BOM ææï¼åå¹¶ææå·¥åºç bomItemsï¼æ itemId å»éï¼ |
| | | saveWorkOrderBomFromProcesses(workOrderId, list); |
| | | |
| | | // 5. é建工åºé¾ |
| | | rebuildProcessChain(workOrderId); |
| | | } |
| | | |
| | | /** |
| | | * ä»å·¥åºåè¡¨ä¸æå BOM ææï¼åå¹¶å»éåä¿åå°å·¥å BOM 表 |
| | | */ |
| | | private void saveWorkOrderBomFromProcesses(Long workOrderId, List<MesProWorkOrderProcessSaveReqVO> list) { |
| | | // æ¶éææå·¥åºç bomItemsï¼æ itemId å»éï¼ä¿ç第ä¸ä¸ªåºç°ç quantityï¼ |
| | | java.util.Map<Long, MesProWorkOrderProcessSaveReqVO.BomItem> merged = new java.util.LinkedHashMap<>(); |
| | | for (MesProWorkOrderProcessSaveReqVO item : list) { |
| | | if (CollUtil.isNotEmpty(item.getBomItems())) { |
| | | for (MesProWorkOrderProcessSaveReqVO.BomItem bomItem : item.getBomItems()) { |
| | | if (bomItem.getItemId() != null) { |
| | | merged.putIfAbsent(bomItem.getItemId(), bomItem); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // å 餿§ BOMï¼æ¹éæå
¥æ° BOM |
| | | workOrderBomService.deleteWorkOrderBomByWorkOrderId(workOrderId); |
| | | if (CollUtil.isNotEmpty(merged)) { |
| | | List<MesProWorkOrderBomDO> bomList = new ArrayList<>(merged.size()); |
| | | for (MesProWorkOrderProcessSaveReqVO.BomItem bomItem : merged.values()) { |
| | | bomList.add(MesProWorkOrderBomDO.builder() |
| | | .workOrderId(workOrderId) |
| | | .itemId(bomItem.getItemId()) |
| | | .quantity(bomItem.getQuantity()) |
| | | .remark(bomItem.getRemark()) |
| | | .build()); |
| | | } |
| | | workOrderBomMapper.insertBatch(bomList); |
| | | } |
| | | } |
| | | |
| | | // ==================== ç§ææ¹æ³ ==================== |
| | | |
| | | private MesProWorkOrderProcessDO validateWorkOrderProcessExists(Long id) { |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDetailDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | |
| | | @Resource |
| | | private MesWmItemConsumeDetailService itemConsumeDetailService; |
| | | @Resource |
| | | private MesProRouteProductBomService routeProductBomService; |
| | | @Resource |
| | | private MesProRouteService routeService; |
| | | private MesProWorkOrderBomService workOrderBomService; |
| | | @Resource |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | |
| | | |
| | | @Override |
| | | public MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback) { |
| | | // 1.1 é¿å
routeId ç为 null æ¶ getRouteProductBomList å eqIfPresent æ¾å®½æ¡ä»¶å¯¼è´è¯¯æ¥ |
| | | if (feedback.getRouteId() == null || feedback.getProcessId() == null || feedback.getItemId() == null) { |
| | | // 1.1 æ ¡éªå·¥åç¼å·ææ |
| | | if (feedback.getWorkOrderId() == null) { |
| | | throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID); |
| | | } |
| | | routeService.validateRouteExists(feedback.getRouteId()); |
| | | // 1.2 æ¥è¯¢å½åå·¥åºç BOM ç©æé
ç½® |
| | | List<MesProRouteProductBomDO> boms = routeProductBomService.getRouteProductBomList( |
| | | feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId()); |
| | | // 1.2 æ¥è¯¢å·¥å BOM ç©æå表ï¼å岿工忿ï¼éå·¥èºè·¯çº¿ï¼ |
| | | List<MesProWorkOrderBomDO> boms = workOrderBomService.getWorkOrderBomListByWorkOrderId( |
| | | feedback.getWorkOrderId()); |
| | | if (CollUtil.isEmpty(boms)) { |
| | | return null; |
| | | } |
| | |
| | | <!-- CONSOLE_LOG_PATTERN ç¸æ¯ FILE_LOG_PATTERN å¤äº highlightãcyan çé«äº® --> |
| | | <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n"/> |
| | | <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n"/> |
| | | <!-- æä¹
å error æ¥å¿è·¯å¾ï¼æå¤©æ»å¨ï¼ä¿ç 15 天 --> |
| | | <property name="ERROR_LOG_FILE" value="./logs/error/error.log"/> |
| | | |
| | | <!-- æ§å¶å° Appender --> |
| | | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">ããããã |
| | |
| | | <appender-ref ref="FILE"/> |
| | | </appender> |
| | | |
| | | <!-- Error æ¥å¿ä¸æ Appenderï¼æä¹
å error æ¥å¿ï¼æå¤©æ»å¨ï¼ä¿ç 15 天 --> |
| | | <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- åªåå
¥ ERROR çº§å« --> |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>ERROR</level> |
| | | </filter> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${FILE_LOG_PATTERN}</pattern> |
| | | </encoder> |
| | | <file>${ERROR_LOG_FILE}</file> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <fileNamePattern>${ERROR_LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern> |
| | | <maxHistory>15</maxHistory> |
| | | </rollingPolicy> |
| | | </appender> |
| | | <!-- 弿¥åå
¥ error æ¥å¿ --> |
| | | <appender name="ERROR_ASYNC" class="ch.qos.logback.classic.AsyncAppender"> |
| | | <discardingThreshold>0</discardingThreshold> |
| | | <queueSize>512</queueSize> |
| | | <appender-ref ref="ERROR_FILE"/> |
| | | </appender> |
| | | |
| | | <!-- SkyWalking Appenderï¼GRPC æ¥å¿æ¶éï¼å®ç°æ¥å¿ä¸å¿ --> |
| | | <!-- |
| | | <appender name="SKYWALKING" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"> |
| | |
| | | <appender-ref ref="ASYNC"/> |
| | | <!-- å¦ææ³æ¥å
¥ãSkyWalking æ¥å¿æå¡ãï¼å¯ä»¥åæ¶æ³¨éææ¬è¡ --> |
| | | <!-- <appender-ref ref="SKYWALKING"/> --> |
| | | <!-- Error æ¥å¿æä¹
åï¼æå¤©æ»å¨ï¼ä¿ç 15 天 --> |
| | | <appender-ref ref="ERROR_ASYNC"/> |
| | | </root> |
| | | |
| | | </configuration> |