feat(mes): 重构袋码生成与物料分类功能
- 移除托盘容量超限错误码定义
- 添加品种主计量单位类型配置相关错误码
- 删除物料分类相关字段和查询逻辑
- 新增计量单位类型字段支持48千克/100千克/吨
- 实现按品种主单位类型生成袋码的业务逻辑
- 添加原始袋码生成功能支持直接指定数量
- 优化袋码绑定批次和托盘的业务流程
- 更新API接口适配新的数据结构变化
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # åç§ç®¡ç廿ãåç§åç±»ããéè´ä»·ã - å端èè°æ¹æ¡ |
| | | |
| | | ## èæ¯ |
| | | |
| | | åºç¡æ°æ®-åç§ç®¡çä¸åç»´æ¤ãåç§åç±»ãåãéè´ä»·ãä¸¤ä¸ªåæ®µï¼ |
| | | |
| | | - æ°æ®åºå `mdm_item.category_id`ã`mdm_item.purchase_price` ä¿çï¼å岿°æ®ä¸å ï¼ï¼ä½æ¥å£å±ä¸åæ¥æ¶åè¿åã |
| | | - MDMâMES 忥ä¸åä¼ åç§åç±»ï¼åæ¥çæç MES ç©æãç©æåç±»ã为空ï¼å¯å¨ MES ç©æäº§åé¡µé¢æå·¥è¡¥å¡«ã |
| | | - MESâMDM åå忥ï¼MES ç©æå¾éãåæ¥å° MDMãåååç±»ï¼ä¿æä¸åã |
| | | |
| | | ## API åå |
| | | |
| | | | æ¹æ³ | è·¯å¾ | åå | |
| | | |------|------|------| |
| | | | POST | /mdm/item/create | 请æ±ä½ä¸åæ¥æ¶ `categoryId`ã`purchasePrice`ï¼ä¼ å
¥å°è¢«å¿½ç¥ï¼ | |
| | | | PUT | /mdm/item/update | åä¸ | |
| | | | GET | /mdm/item/get | ååºä¸åè¿å `categoryId`ã`categoryName`ã`purchasePrice` | |
| | | | GET | /mdm/item/page | ååºä¸åè¿åä¸è¿°ä¸å段ï¼ä¸åæ¯æ `categoryId` æ¥è¯¢åæ° | |
| | | | GET | /mdm/item/simple-list | ååºä¸åè¿åä¸è¿°ä¸å段 | |
| | | | GET | /mdm/item/list-by-ids | ååºä¸åè¿åä¸è¿°ä¸å段 | |
| | | |
| | | **ååºç¤ºä¾ï¼èéï¼ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "list": [ |
| | | { |
| | | "id": 1, |
| | | "code": "PZ0001", |
| | | "name": "水稻åç§A", |
| | | "specification": "500g/è¢", |
| | | "unitMeasureId": 2, |
| | | "unitMeasureName": "è¢", |
| | | "salesPrice": 15.00, |
| | | "syncedMes": true |
| | | } |
| | | ], |
| | | "total": 1 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## å端修æ¹ç¹ï¼æ¬æ¹å·²åæ¥ä¿®æ¹ï¼ä¾å端å¢é夿 ¸ï¼ |
| | | |
| | | ### 1. åç§ç®¡ç页é¢ï¼src/views/basicData/mdm/ï¼ |
| | | |
| | | | æä»¶ | ä¿®æ¹å
容 | |
| | | |------|----------| |
| | | | data.ts | å é¤è¡¨åãåç§åç±»ãTreeSelectããéè´ä»·ãInputNumberï¼å é¤å表ãåç§åç±»ããéè´ä»·ãåï¼å é¤ `buildCategoryTree` å MES ç©æåç±»æ¥å£ import | |
| | | | index.vue | å é¤åç±»å表ç¼åãåç±»åç§°/é¢è²å·¥å
·å½æ°ã`#categoryName` ææ§½ååç±»å è½½é»è¾ | |
| | | | modules/form.vue | å 餿å¼è¡¨åæ¶å è½½åç±»æ çé»è¾ | |
| | | | components/data.ts | åç§éæ©å¼¹çªå é¤ãåç§åç±»ãæç´¢é¡¹ä¸å | |
| | | | components/select-dialog.vue | å é¤åç±»ç¼åãåç§°/é¢è²å½æ°ã`#categoryId` ææ§½ååç±»å è½½é»è¾ | |
| | | |
| | | ### 2. API ç±»åï¼src/api/mdm/item/index.tsï¼ |
| | | |
| | | - `MdmItemApi.Item` å é¤ `categoryId`ã`categoryName`ã`purchasePrice`ã |
| | | - `MdmItemApi.PageParams` å é¤ `categoryId`ã |
| | | |
| | | ### 3. ä¾èµéè´ä»·èªå¨ç®ä»·ç忮页ï¼è¡ä¸ºååï¼éç¹å¤æ ¸ï¼ |
| | | |
| | | åç§ä¸åæéè´ä»·ï¼ä»¥ä¸ä¸¤å¤éååãåä»·ãä¸åèªå¨å¸¦å
¥ï¼æ¹ä¸ºé»è®¤ 0ãç±ç¨æ·æå·¥å¡«åï¼ |
| | | |
| | | | æä»¶ | ä¿®æ¹å
容 | |
| | | |------|----------| |
| | | | src/views/erp/purchase/order/modules/item-form.vue | éæ©åç§å `productPrice` ä¸ååéè´ä»·ï¼ç½® 0 æå·¥å¡«å | |
| | | | src/views/erp/purchase/request/modules/item-form.vue | åä¸ | |
| | | |
| | | å
¶ä½åæ®ï¼éå®ãåºåçï¼ä½¿ç¨çæ¯ ERP 产åï¼`erp_product`ï¼èªèº«ä»·æ ¼æéå®ä»·ï¼ä¸åå½±åã |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | æ°å¢/ç¼è¾åç§ | æ åç±»ãæ éè´ä»·å段ï¼ä¿åæ¥å£å¿½ç¥è¿ä¸¤ä¸ªå
¥å | |
| | | | ç¼è¾åå²åç§ | åå²å·²å¡«çåç±»/éè´ä»·å¨æ´æ°æ¶ä¸ä¼è¢«æ¸
空ï¼ä»
ä¸ååæ¾ï¼ï¼ä¹ä¸ä¼è¢«è¦ç | |
| | | | åç§åæ¥å° MES | çæç MES ç©æäº§åãç©æåç±»ã为空ï¼MES ç©æäº§å页é¢ä»å¯æå·¥è¡¥å¡«åç±» | |
| | | | MES ç©æå¾éåæ¥å° MDM | åç±»åå `mdm_item.category_id` ä¿æåé»è¾ï¼åç§ç®¡ç页é¢ä¸å±ç¤ºè¯¥å¼ï¼ | |
| | | | åç§åç±»ç®¡çæ¨¡å | 䏿¹å¨ï¼åç±»æ°æ®ä»ä¾ MES ç©æåç±»çåºæ¯ä½¿ç¨ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - éå®ä»·ãææ¬ä»·æªä¸çº¿ï¼è¡¨åä¸åè¡¨ä¿æåæ ·ã |
| | | - å表å é¤ä¸¤ååå宽èªè¡å¾®è°ã |
| | | - åç§éæ©å¼¹çªï¼MdmItemSelect/MdmItemSelectDialogï¼è¢«éè´ãåºåçå¤å¤ä¸å¡é¡µå¤ç¨ï¼å é¤åç±»åå请åå½éªè¯éå带å
¥ï¼ç¼ç /åç§°/åä½/æ¡ç ï¼æ¯å¦æ£å¸¸ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # MDM 计éå使°å¢ãç±»åãåæ®µ - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - åºç¡æ°æ® > MDM > 计éåä½ï¼åè¡¨ãæ°å¢/ç¼è¾å¼¹çªï¼ |
| | | |
| | | ## API |
| | | |
| | | æ¥å£è·¯å¾ä¸åï¼ä»
请æ±/ååºä½æ°å¢ `type` åæ®µã |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | /mdm/unit/create | å建计éåä½ï¼è¯·æ±ä½æ°å¢ typeï¼ | |
| | | | PUT | /mdm/unit/update | æ´æ°è®¡éåä½ï¼è¯·æ±ä½æ°å¢ typeï¼ | |
| | | | GET | /mdm/unit/get | è·å¾è®¡éåä½ï¼ååºæ°å¢ typeï¼ | |
| | | | GET | /mdm/unit/page | è·å¾è®¡éåä½å页ï¼ååºæ°å¢ typeï¼ | |
| | | | GET | /mdm/unit/list | è·å¾è®¡éåä½å表ï¼ååºæ°å¢ typeï¼ | |
| | | |
| | | **请æ±åæ°ï¼æ°å¢ï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | type | String | æ¯ | ç±»åï¼åéï¼å¯éå¼åºå®ä¸ºï¼`48åå
`ã`100åå
`ã`å¨`ï¼ä¸éä¸ï¼ç´æ¥åææ¬ï¼å端 `@NotBlank` æ ¡éªï¼ | |
| | | |
| | | **ååºåæ®µï¼æ°å¢ï¼ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | type | String | ç±»åï¼å岿°æ®ä¸º null | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "id": 1, |
| | | "code": "BAG", |
| | | "name": "è¢", |
| | | "type": "48åå
", |
| | | "status": 0 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## å端修æ¹ç¹è¯´æï¼å·²éæ¬æ¬¡å端æ¹å¨ä¸å¹¶å®æï¼ä¾æ ¸å¯¹ï¼ |
| | | |
| | | | ä½ç½® | è¦æ± | |
| | | |------|------| |
| | | | æ°å¢/ç¼è¾å¼¹çªè¡¨å | å¢å ãç±»åã䏿鿩ï¼é项åºå®ä¸é¡¹ï¼48åå
/ 100åå
/ å¨ï¼åéãå¿
å¡« | |
| | | | åè¡¨è¡¨æ ¼ | å¢å ãç±»åãåå±ç¤ºï¼ç©ºå¼æ¾ç¤ºä¸º `-` | |
| | | | æ¥è¯¢è¡¨å | æä¸æä¾ç±»åçéï¼å端å页æ¥å£æªå è¯¥è¿æ»¤æ¡ä»¶ï¼ | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | åéæ°æ® | èè®°å½ `type` 为空ï¼å表å±ç¤º `-`ï¼ç¼è¾èè®°å½æ¶å¿
须补éç±»ååæè½ä¿åï¼åç«¯å¼ºæ ¡éªï¼ | |
| | | | éé¡¹æ¥æº | é项为åç«¯åæ»ä¸é¡¹ææ¬ï¼ä¸å»ºæ°æ®åå
¸ï¼æäº¤ç value å³ä¸æææ¬æ¬èº« | |
| | | | åç«¯æ ¡éª | `@NotBlank` å¿
å¡«æ ¡éªï¼åå¼èå´ä¸éå¶ï¼åç«¯ä¸æéä¿è¯åªä¼æäº¤ä¸ä¸ªåºå®å¼ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `type` ä¸ºææ¬åæ®µï¼VARCHAR(20)ï¼ï¼ä¿åæ¶ä¼ 䏿åæï¼ä¸è¦ä¼ ç¼ç ææ°åã |
| | | - è¯¥åæ®µå¿
å¡«ï¼ä¸ºç©ºæ¶æ¥å£è¿ååæ°æ ¡éªé误ãç±»åä¸è½ä¸ºç©ºãã |
| | | - 计éåä½è¢«ç©æå¼ç¨åä»å¯ä¿®æ¹ç±»åï¼æ 级èéå¶ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ä¸è¢ä¸ç ç产é»è¾æ¹é - å端èè°æ¹æ¡ |
| | | |
| | | > é
å¥éæ±æ¹æ¡ï¼`docs/mes_bag_code_package_refactor_requirements.md`ãæ¬æ¹æ¡è¦çæ¥å£åæ´ä¸é¡µé¢æ°æ®å¸¦å
¥ï¼åç«¯ä¸»ä½æ¹å¨å·²éæ¬æ¬¡æ¹é 忥宿ï¼ä¾èè°åå½ä½¿ç¨ã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - èµç 管çï¼è¢ç ï¼ï¼çææ°æ®å
å¼¹çªãçæåå§è¢ç å¼¹çªãè¢ç å表ãå½å
¥æ¹æ¬¡ãç»å®æçãè¿½æº¯å¼¹çª |
| | | - çäº§æ¹æ¬¡ï¼æ°å¢/ç¼è¾/è¡¥å½è¡¨åï¼æ°å¢ãç»å®æçãå¤éï¼ãå表ãæç´¢åº |
| | | - æç管çï¼é¢çæå¼¹çªãå表ãç»å®æ¹æ¬¡å¼¹çª |
| | | - å
Œ
± H5 溯æºé¡µãæ«ç 追溯弹çªï¼åå½ï¼ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. çææ°æ®å
ï¼éåç§ â å端æåç§ä¸»è®¡éåä½ç±»åèå¨ï¼æ¥ `/mdm/item/get` å `unitMeasureId`ï¼åæ¥ `/mdm/unit/get?id=` å `type`ï¼ï¼ |
| | | - `48åå
`/`100åå
` â è¾å
¥**æçæ°**ï¼é¢è§ãæ¯æ N è¢ Ã æçæ° = è¢ç æ°ã |
| | | - `å¨` â è¾å
¥**è¢ç æ°**ï¼æ æçï¼ |
| | | - ç±»åæªé
ç½® â æç¤ºåå¾ã计éåä½ãç»´æ¤ï¼æäº¤æ¶å端ä¹ä¼å
åºæ¥é |
| | | 2. çæç»æï¼åä¸ uuid è¢ç ç» + èªå¨çæçä¸´æ¶æçï¼PL-åºå·ï¼ï¼è¢ç 已带åç§ãå·²ç»æçã |
| | | 3. å½å
¥æ¹æ¬¡ï¼å¾éè¢ç â éçäº§æ¹æ¬¡ãå端级èï¼ä¸´æ¶æç忣å¼ç ï¼æ¹æ¬¡å·-Påºå·ï¼å¹¶ç»æ¹æ¬¡ãååè¢ç å使çç ãæ··åç§ä¼è¢«æ¦æªã |
| | | 4. æ¹æ¬¡ä¸åå½å
¥/å±ç¤ºåç§ï¼åç§ä¿¡æ¯å
¨é¨ç±è¢ç æ°æ®å
æºå¸¦ã |
| | | 5. æ°å¢/è¡¥å½/ç¼è¾æ¹æ¬¡æ¶åå¯éãç»å®æçãï¼å¤éãéå¿
å¡«ï¼æ°æ®æº `GET /mes/pro/pallet/unbound-list`ï¼å±ç¤ºä¸´æ¶æçç +å·²è£
è¢æ°ï¼ï¼å¾éåæ¹æ¬¡ç¶æç´æ¥ä¸º**ç产ä¸**ï¼å端åäºå¡å¤ç¨æçç»å®æ¹æ¬¡é»è¾ï¼æç忣å¼ç ãæçä¸è¢ç 级èå½å
¥ï¼ï¼ä»»ä¸æ ¡éªå¤±è´¥æ´ä½åæ»ï¼ç¼è¾æ¶ä»
éå¾éæ¬æ¬¡æ°å¢çæçï¼å·²ç»å®æçä¸å¨ä¸æä¸ãä¸å¯è§£ç»ï¼ã |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | åæ´ | |
| | | |------|------|------| |
| | | | POST | /mes/pro/bag-code/generate | 请æ±/ååºç»æåæ´ï¼è§ä¸ï¼ | |
| | | | POST | /mes/pro/bag-code/raw-generate | **æ°å¢**ï¼çæåå§è¢ç ï¼è¯·æ± `{ itemId, count, remark? }`ï¼ä»
ææ°éçæã䏿¢ç®è®¡éåä½ç±»åãä¸çææçï¼ååºç»æå generateï¼`type/perPallet` 为空ã`palletIds` 空æ°ç»ï¼ | |
| | | | PUT | /mes/pro/bag-code/bind-batch | è·¯å¾ä¸åï¼æ°å¢åç§ä¸è´æ ¡éªãæç级èç»å®ï¼å·²å¯¼åºå°å·ï¼PRINTEDï¼è¢ç ä¹å
许å½å
¥æ¹æ¬¡ | |
| | | | PUT | /mes/pro/pallet/bind-batch | è·¯å¾ä¸åï¼æçç»å®æ¹æ¬¡æ¶ï¼æç䏿ªç»æ¹æ¬¡çè¢ç èªå¨çº§èå½å
¥å䏿¹æ¬¡ï¼åç§ä¸è´æ ¡éªãååæ¹æ¬¡è¢æ°ï¼ | |
| | | | DELETE | /mes/pro/bag-code/delete-by-uuid | è·¯å¾ä¸åï¼çº§èå 餿¬ç»èªå¨çææç | |
| | | | POST | /mes/pro/bag-code/replace | ä¸åï¼æ°è¢ç èªå¨ç»§æ¿ååç§ | |
| | | | GET | /mes/pro/bag-code/pageãlist-by-uuidãget-by-code | ååºæ°å¢åç§å段ï¼page æ°å¢å¯éæ¥è¯¢åæ° `itemId`ï¼åç§ï¼çå¼å¹é
ï¼å¯¼åº Excel åå£å¾ï¼ | |
| | | | POST | /mes/pro/pallet/batch-createãpre-generate | 请æ±å»æ capacity | |
| | | | GET | /mes/pro/pallet/page | ååºå»æ capacityï¼ä¿ç autoGenerated | |
| | | | POST/PUT | /mes/pro/batch/createãupdateãfill-info | 请æ±å»æ itemIdï¼ä¸è
åæ°å¢å¯é `palletIds`ï¼ç»å®æ¶æ¹æ¬¡è¿å
¥ç产ä¸ï¼ | |
| | | | GET | /mes/pro/pallet/unbound-list | **æ°å¢**ï¼æªç»å®æ¹æ¬¡çä¸´æ¶æçåè¡¨ï¼æé mes:pro-pallet:queryï¼ï¼ä¾æ¹æ¬¡æ°å¢/è¡¥å½ç»å®æç䏿 | |
| | | | GET | /mes/pro/batch/pageãgetãsimple-list | ååºå»æ itemId/itemCode/itemName/itemSpecification | |
| | | |
| | | **çææ°æ®å
请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | itemId | Long | æ¯ | åç§ç¼å· | |
| | | | palletCount | Integer | æ¡ä»¶å¿
å¡« | æçæ°ï¼ç±»å=Nåå
ï¼ | |
| | | | bagCount | Integer | æ¡ä»¶å¿
å¡« | è¢ç æ°ï¼ç±»å=å¨ï¼ | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | |
| | | **çææ°æ®å
ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "uuid": "çæç»UUID", |
| | | "type": "48åå
", |
| | | "perPallet": 48, |
| | | "totalCount": 96, |
| | | "palletIds": [101, 102] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | åç§ç¼ç /åç§°ï¼itemCode/itemNameï¼ | è¢ç å表ã追溯ãå¯¼åº Excel | çææ¶ç»å®å¨è¢ç ä¸ | |
| | | | autoGenerated | æçå表ãèªå¨çæãTag | æ°æ®å
èªå¨å建çæçæ è¯ | |
| | | | åç§ï¼æ¹æ¬¡é¡µï¼ | ä¸åå±ç¤º | 表å/å表/æç´¢åå·²ç§»é¤ | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | ç±»å=Nåå
çæ | è¢ç æ° = N à æçæ°ï¼èªå¨å»º N 个æçå¹¶ååç»å® | |
| | | | ç±»å=å¨ çæ | æ æçï¼è¢ç ä»
ç»æ¹æ¬¡ | |
| | | | çæåå§è¢ç | ä»
éåç§+æ°éï¼è¢ç 带åç§ãä¸ç»æ¹æ¬¡/æçï¼åç»å½å
¥æ¹æ¬¡ãç»æçã导åºå°å·ãå é¤ç»ä¸æ°æ®å
è¢ç å®å
¨ä¸è´ï¼ä¸æ ¡éªåç§è®¡éåä½ç±»å | |
| | | | å½å
¥æ¹æ¬¡æ··åç§ | æ¥éãå½å
¥æ¹æ¬¡çè¢ç å¿
é¡»å±äºåä¸åç§ãï¼ä¸æ¹æ¬¡å·²æè¢ç ä¸å¹¶æ ¡éªï¼ | |
| | | | æçç»å®æ¹æ¬¡ | æç䏿ªç»æ¹æ¬¡çè¢ç ï¼å·²çæ/已导åºå°å·ï¼èªå¨éæçå½å
¥å䏿¹æ¬¡ï¼è¢ç å使çç åæ¥æ´æ°ä¸ºæ£å¼ç | |
| | | | æ¹æ¬¡æ°å¢/è¡¥å½/ç¼è¾ç»å®æç | palletIds éç©ºæ¶æ¹æ¬¡ç¶æç´æ¥ç½®ãç产ä¸ãï¼åäºå¡å¤ç¨æçç»å®æ¹æ¬¡é»è¾ï¼æ£å¼ç +è¢ç 级è+åç§ä¸è´æ ¡éªï¼ï¼å¤±è´¥æ´ä½åæ»ï¼æ°å¢/è¡¥å½æªå¾éåç»´æè稿ï¼ç¼è¾åæ¶å¾éä¸åéç¶æãå·²ç»å®æçä¸å¯è§£ç» | |
| | | | ç»æç容é | æ ä¸éï¼èªå¨æçå¯ç»§ç»æå¨ç»å
¥ | |
| | | | å 餿°æ®å
| ç»å
æçå·²ç»æ¹æ¬¡æææ£å¼ç åä¸å¯å ï¼å¦å级èå èªå¨æç | |
| | | | 追溯åç§ | ä¼å
è¢ç åç§ï¼åå²è¢ç åéæ¹æ¬¡åç§ï¼å
Œ
± H5 åæ¥æ¯æï¼ | |
| | | | æ¹æ¬¡å· | PC + yyyyMMdd + 产线ç¼ç + æµæ°´å·ï¼ä¸åå«åç§ç¼ç ï¼ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `generate` æ§åæ° `count` å·²åºå¼ï¼åªä¼ `palletCount` æ `bagCount`ï¼æåç§ç±»åäºéä¸ï¼ã |
| | | - æ¹æ¬¡ `itemId` ç¸å
³åæ®µå·²ä»æ¥å£ç§»é¤ï¼å¿åå¼ç¨ï¼æ¹æ¬¡è¿½æº¯è§å¾ `get-by-code` çåç§å段ä¿çï¼å¯è½ä¸ºç©º=æ°æ¹æ¬¡ï¼ã |
| | | - æç追溯è§å¾ï¼PalletTrace/qr-trace-modalï¼ä»è¿å `capacity` ä¾å岿°æ®å±ç¤ºï¼æ°æç为空ã |
| | | - èæ°æ®ï¼åå²ç©ºç½è¢ç ï¼åç§ä¸ºç©ºå±æ£å¸¸ï¼è¿½æº¯èµ°æ¹æ¬¡åéã |
| | | - `palletIds` å¨ create/update/fill-info åçæï¼ä¸ææ¯æ¬¡æå¼å¼¹çªéæ°æå `unbound-list`ï¼è¥æäº¤æ¶æéæç已被ä»äººç»å®ï¼å端æ´ä½æ¥éåæ»ï¼æ¬æ¬¡æ¹æ¬¡æä½ä¸çæï¼ï¼æç¤ºç¨æ·å·æ°éè¯ã |
| | | - è¢ç å页ï¼`/page`ï¼å端已æ¹ä¸º**å建æ¶é´ååº**ï¼åç§å
æç¼å·ååºï¼ï¼å端æ éåä¼ æåºåæ°ï¼å¯¼åº Excel åå£å¾ã |
| | | - åå§è¢ç 䏿°æ®å
è¢ç å表åè§åï¼uuid æç»ã坿´ç»å é¤ï¼ï¼å表页éè¿çæç» UUID åºåæ¥æºã |
| | | - å表æç´¢åºæ°å¢ãåç§ãæ¡ä»¶ï¼å¤ç¨ `MdmItemSelect`ï¼å¯æ¸
空ï¼ï¼ä¼ `itemId` çå¼è¿æ»¤ï¼å¯¼åº Excel æºå¸¦å䏿¥è¯¢æ¡ä»¶åå£å¾çæãåå²ç©ºç½è¢ç åç§ä¸ºç©ºï¼æåç§çéä¸ä¼å½ä¸ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ä¸è¢ä¸ç ç产é»è¾æ¹é - éæ±æ¹æ¡ |
| | | |
| | | > ç¶æï¼å·²ç¡®è®¤å¹¶å®æå®æ½ï¼2026-09-17ï¼ãå³çç¹å®ç¨¿è§ææ«ã6. 确认ç»è®ºãã |
| | | |
| | | ## 1. éæ±èæ¯ |
| | | |
| | | ä¸è¢ä¸ç çç产é»è¾è°æ´ï¼ |
| | | |
| | | - æ¹æ¬¡ç产管ç**ä¸åç»å®åç§**ï¼åç§ä¸æ²å°ãèµç 管çãçæ°æ®å
ä¸ã |
| | | - çææ°æ®å
æ¶éæ©**åç§**å¹¶è¾å
¥**æçæ°**ï¼ç³»ç»æåç§ä¸»è®¡éåä½çãç±»åãèªå¨è®¡ç®è¢ç æ°éå¹¶çæè¢ç ã |
| | | - ææçæ°**èªå¨çææçå¹¶èªå¨ç»å®**è¢ç ï¼æçä¸åéè¦ãå¯è£
è¢æ°ãã |
| | | - åç§ä¸ºãå¨ãæ¶æ æçï¼æ¹ä¸ºç´æ¥è¾å
¥**è¢ç æ°**ï¼è¢ç åªç»çäº§æ¹æ¬¡ãä¸ç»æçç ã |
| | | |
| | | ## 2. ç°ç¶è¦ç¹ |
| | | |
| | | | 对象 | ç°ç¶ | |
| | | |------|------| |
| | | | æ°æ®å
çæ | `POST /mes/pro/bag-code/generate` ä»
ä¼ `count`ï¼çæç©ºç½è¢ç ï¼æ åç§/æ¹æ¬¡/æçï¼ | |
| | | | æ¹æ¬¡ | `mes_pro_batch.itemId` ç»å®åç§ï¼æ¹æ¬¡å· = PC + æ¥æ + 产线ç¼ç + åç§ç¼ç + æµæ°´å· | |
| | | | æç | æå¨åå»ºï¼æ¹éçæ/é¢çæï¼ï¼å建æ¶å¡« `capacity å¯è£
è¢æ°`ï¼è¢ç æå¨ç»æçå¹¶æ ¡éªå®¹é | |
| | | | åç§âåä½ | `mdm_item.unitMeasureId â mdm_unit_measure.type`ï¼ç±»åé项ï¼48åå
/100åå
/å¨ï¼æ¬æ¬¡å·²å ï¼ | |
| | | | 追溯 | æ«ç 追溯çåç§ä¿¡æ¯åèªæ¹æ¬¡ `batch.itemId` | |
| | | |
| | | ## 3. æ¹é æ¹æ¡ |
| | | |
| | | ### 3.1 çææ°æ®å
ï¼èµç 管çï¼æ ¸å¿æ¹å¨ï¼ |
| | | |
| | | **æ¢ç®è§å**ï¼å端计ç®ï¼ä¸ä¿¡ä»»åç«¯ä¼ å¼ï¼ï¼ |
| | | |
| | | | åç§ä¸»åä½ç±»å | è¾å
¥ | çæç»æ | |
| | | |------|------|------| |
| | | | 48åå
| æçæ° P | è¢ç 48 à P 个ï¼èªå¨çæ P 个æçï¼æ¯æç»å® 48 个è¢ç | |
| | | | 100åå
| æçæ° P | è¢ç 100 à P 个ï¼èªå¨çæ P 个æçï¼æ¯æç»å® 100 个è¢ç | |
| | | | å¨ | è¢ç æ° N | è¢ç N 个ï¼ä¸çææçï¼è¢ç ä¸ç»æç | |
| | | | ç±»å为空/æ æ³è§£æ | - | æ¥éï¼åç§ä¸»è®¡éå使ªé
置类åï¼48åå
/100åå
/å¨ï¼ | |
| | | |
| | | **æ¥å£åæ´** `POST /mes/pro/bag-code/generate`ï¼ |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | itemId | Long | æ¯ | åç§ï¼mdm_item ç¼å·ï¼ | |
| | | | palletCount | Integer | æ¡ä»¶å¿
å¡« | æçæ°ï¼ç±»å为 Nåå
æ¶å¿
å¡«ï¼ | |
| | | | bagCount | Integer | æ¡ä»¶å¿
å¡« | è¢ç æ°ï¼ç±»å为 å¨ æ¶å¿
å¡«ï¼ | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | |
| | | ååºæ°å¢ï¼`uuidãtypeãperPalletï¼æ¯æè¢æ°ï¼ãtotalCountï¼çæè¢ç æ°ï¼ãpalletIdsï¼èªå¨çæçæçï¼`ã |
| | | |
| | | **äºå¡é»è¾**ï¼ä¸æ¬¡çæ = åä¸ uuid çè¢ç ç» + åæ¹èªå¨çæçæçï¼æçå
以**临æ¶ç ï¼PL-åºå·ï¼**è½åºå¹¶å®æè¢ç ç»å®ï¼æ£å¼æçç å¨ãå½å
¥æ¹æ¬¡ãæ¶çæã |
| | | |
| | | **çææ°æ®å
å¼¹çªï¼å端ï¼**ï¼éæ©åç§ï¼æ²¿ç¨åç§éæ©ç»ä»¶ï¼â 读å该åç§ä¸»åä½ç±»åï¼åç«¯æ¥ `mdm_unit_measure`ï¼ç±»åä¸ºç©ºç»æç¤ºï¼â æç±»å忢è¾å
¥ãæçæ°ãæãè¢ç æ°ãâ 宿¶é¢è§"å°çæ è¢ç X 个 / æç Y 个"ã |
| | | |
| | | ### 3.2 å½å
¥æ¹æ¬¡ï¼ä¿æåå½å
¥ï¼æ©å±çº§èï¼ |
| | | |
| | | `PUT /mes/pro/bag-code/bind-batch` æµç¨ä¸åï¼æ°å¢çº§èï¼ |
| | | |
| | | 1. è¢ç ç»å®æ¹æ¬¡ï¼ç°ç¶ï¼ã |
| | | 2. 该ç»è¢ç æç»å®çä¸´æ¶æçèªå¨ç»å®å䏿¹æ¬¡ï¼å¹¶åé
æ£å¼æçç `æ¹æ¬¡å·-Påºå·`ï¼ååæ¹æ¬¡æçæ°ã |
| | | 3. æ°å¢æ ¡éªï¼å䏿°æ®å
ï¼åæ¹ç»å®è¢ç ï¼åç§å¿
é¡»ä¸è´ï¼çææ¶å¤©ç¶ä¸è´ï¼é²æå¨æ··éï¼ã |
| | | |
| | | ### 3.3 è¢ç æ°æ®æ¨¡å |
| | | |
| | | `mes_pro_bag_code` æ°å¢ï¼`item_id`ã`item_code`ã`item_name`ï¼åä½ï¼ã |
| | | |
| | | - å表/æ¥è¯¢ï¼æ¾ç¤ºåç§åï¼ç¼ç /åç§°å¯æ£ç´¢æ¬æä¸åï¼ä»
å±ç¤ºï¼ã |
| | | - å 餿°æ®å
ï¼delete-by-uuidï¼ï¼çº§èå 餿¬ç»**èªå¨çæ**çæçï¼åæä»æ¯å
¨é¨æªç»æ¹æ¬¡ï¼å·²å½æ¹æ¬¡ç»´æç°ç¶ä¸å¯å ï¼ã |
| | | - è¢ç ä¸å¼ºå¶æçï¼`pallet_id` ä¿æå¯ç©ºï¼å¨ç±»åï¼ã |
| | | |
| | | ### 3.4 æ¹æ¬¡ç产管ç |
| | | |
| | | - **廿åç§å段**ï¼å建/ç¼è¾è¡¨åãå表åãæ¥è¯¢æ¡ä»¶ãSave/Resp/Page VO åç§»é¤ `itemId`ï¼DO 䏿°æ®åºå `mes_pro_batch.item_id` ä¿çï¼å岿°æ®ã追溯åéç¨ï¼ï¼æ³¨éæ è®°"å·²åºå¼"ã |
| | | - **æ¹æ¬¡å·è§åæ¹ä¸º** `PC + yyyyMMdd + 产线ç¼ç + æµæ°´å·`ï¼`generateBatchCode` ä¸åæ¼åç§ç¼ç ï¼èªå¨ç¼ç è§åé
ç½®æ éæ¹ï¼ã |
| | | - ç¼è¾æ¹æ¬¡ä¸åå åç§ååéæ°çææ¹æ¬¡å·ã |
| | | |
| | | ### 3.5 æç管ç |
| | | |
| | | - æ¹éçæ/é¢çææ¥å£å»æ `capacity` å
¥åï¼è¡¨å廿ãå¯è£
è¢æ°ãåæ®µï¼åè¡¨å»æè¯¥åãDB åä¿çå
¼å®¹åå²ã |
| | | - è¢ç æå¨ç»æçå»æå®¹éæ ¡éªï¼`capacity` å¤ç©ºé»è¾å¤©ç¶è·³è¿ï¼å é¤ç¸å
³æ ¡éªä»£ç ï¼ã |
| | | - æçå表为èªå¨çææçææ è¯ï¼å¤ç¨ `auto_generated` åæ®µ = trueï¼ã |
| | | |
| | | ### 3.6 追溯/æ«ç /çæ¿ï¼åå½é¡¹ï¼ |
| | | |
| | | - è¢ç 追溯ï¼`/get-by-code`ãTraceRespVOï¼ï¼åç§æ¹ä¸º**ä¼å
åè¢ç item_idï¼åå²è¢ç åéæ¹æ¬¡ itemId**ã |
| | | - æ¹æ¬¡è¿½æº¯è§å¾ï¼MesProBatchTraceRespVOï¼ï¼ä¿çåç§è¿åä½å¯è½ä¸ºç©ºï¼å岿¹æ¬¡æå¼ï¼ã |
| | | - æ«ç å
¥åºãéå®åºåºãè¢ç é¦é¡µçæ¿ï¼ä¸ç´æ¥ä¾èµæ¹æ¬¡åç§çé»è¾ä¸å¨ï¼æ¶åå¤åå½éªè¯ã |
| | | |
| | | ## 4. æ°æ®åºåæ´ï¼mom-thzyï¼ |
| | | |
| | | ```sql |
| | | ALTER TABLE mes_pro_bag_code ADD COLUMN item_id BIGINT NULL COMMENT 'åç§ï¼ç©æï¼ç¼å·' AFTER pallet_code; |
| | | ALTER TABLE mes_pro_bag_code ADD COLUMN item_code VARCHAR(64) NULL COMMENT 'åç§ç¼ç ï¼åä½ï¼' AFTER item_id; |
| | | ALTER TABLE mes_pro_bag_code ADD COLUMN item_name VARCHAR(255) NULL COMMENT 'åç§åç§°ï¼åä½ï¼' AFTER item_code; |
| | | -- mes_pro_batch.item_id ä¿çä¸å ï¼Java æ³¨éæ è®°åºå¼ |
| | | ``` |
| | | |
| | | ## 5. åå端æ¹å¨æ¸
å |
| | | |
| | | | å± | æä»¶ | æ¹å¨ | |
| | | |----|------|------| |
| | | | DB | mes_pro_bag_code | +item_id/item_code/item_name | |
| | | | å端 | MesProBagCodeGenerateReqVO/RespVOãServiceImpl | æ°åæ°ãç±»åæ¢ç®ãèªå¨å»ºæçãäºå¡ | |
| | | | å端 | MesProBagCodeDO/RespVO/Mapper | +åç§å段 | |
| | | | å端 | bind-batch æµç¨ | 级èæçç»æ¹æ¬¡ãåç§ä¸è´æ§æ ¡éª | |
| | | | å端 | MesProBatchServiceImpl/VO | å»åç§ãæ¹æ¬¡å·è§åãç¼è¾é»è¾ | |
| | | | å端 | MesProPalletServiceImpl/VO | å» capacity å
¥å䏿 ¡éª | |
| | | | å端 | delete-by-uuid | 级èå èªå¨æç | |
| | | | å端 | 追溯 VO | åç§ä¼å
è¢ç ãåéæ¹æ¬¡ | |
| | | | å端 | pro/bagCode generate-form | åç§+æçæ°/è¢ç æ°è¡¨å | |
| | | | å端 | pro/bagCode å表 | +åç§å | |
| | | | å端 | pro/batch form/list/search | ç§»é¤åç§ | |
| | | | å端 | pro/pallet form/list | ç§»é¤å¯è£
è¢æ° | |
| | | |
| | | ## 6. 确认ç»è®ºï¼å®ç¨¿ï¼ |
| | | |
| | | 1. **æ··åç§**ï¼è¦ã䏿¬¡ bind-batch å¾éçè¢ç åç§å¿
é¡»ä¸è´ï¼å¦åæ¥éãå½å
¥æ¹æ¬¡çè¢ç å¿
é¡»å±äºåä¸åç§ãï¼åå²ç©ºç½è¢ç ä¸å䏿 ¡éªï¼ã |
| | | 2. **èªå¨æçå¯å¦åæå¨å¢ç»**ï¼æ 容éä¸éï¼è£
满åä»å¯ç»§ç»æå¨ç»å
¥è¢ç ã |
| | | 3. **æ¹æ¬¡å表å岿°æ®**ï¼èæ¹æ¬¡ itemId ç´æ¥ä¸å±ç¤ºå³å¯ï¼æ æ°æ®è¿ç§»ï¼è¿½æº¯è§å¾ä¿çæ¹æ¬¡åç§ååå²åéã |
| | | 4. **æµç¨ä¸æ¹æ¬¡å·**ï¼ä¿æãå
çææ°æ®å
ãåå½å
¥æ¹æ¬¡ãï¼æ¹æ¬¡å·è§åæ¹ä¸º `PC + yyyyMMdd + 产线ç¼ç + æµæ°´å·`ã |
| | | |
| | | ## 7. 宿½è®°å½ï¼2026-09-17ï¼ |
| | | |
| | | - DBï¼mom-thzyï¼ï¼`mes_pro_bag_code` æ°å¢ `item_id/item_code/item_name`ï¼`mdm_unit_measure.type`ï¼48åå
/100åå
/å¨ï¼ï¼`mes_pro_batch.item_id` ä¿çæ åºå¼ã |
| | | - å端ï¼`generate` éåï¼ç±»åæ¢ç®+èªå¨ä¸´æ¶æçï¼ã`bind-batch` 级èæçæ£å¼ç +åç§ä¸è´æ ¡éªã`delete-by-uuid` 级èå èªå¨æçã`replace` ç»§æ¿åç§ãæçåå»ºå» `capacity` å
¥åãè¢ç ç»æçå»å®¹éæ ¡éªãæ¹æ¬¡ VO/Service å»åç§ãæ¹æ¬¡å·å产线è¦ç´ ãè¢ç /å
Œ
±è¿½æº¯ä¸äºç»´ç æ ç¾åç§ãè¢ç ä¼å
ãæ¹æ¬¡åéãã |
| | | - å端ï¼è¢ç çæå¼¹çªï¼åç§+æçæ°/è¢ç æ°å¨æ+é¢è§ï¼ãå表åç§åï¼æ¹æ¬¡è¡¨å/å表/æç´¢å»åç§ï¼æç表å/å表å»å¯è£
è¢æ°ãå表å ãèªå¨çæãæ è¯ãç»æç䏿å»å®¹éæç¤ºã |
| | | - ç¼è¯ï¼`mvn compile -pl yudao-module-mes -am -q` éè¿ã |
| | | |
| | | ## 8. è¡¥å
éæ±ï¼æ¹æ¬¡æä½ç»å®æçï¼2026-09-17ï¼ |
| | | |
| | | - æ¹æ¬¡æ°å¢/è¡¥å½/ç¼è¾åå¯éãç»å®æçãï¼å¤éãéå¿
å¡«ï¼ï¼å¾éåæ¹æ¬¡ç¶æç´æ¥ç½®**ç产ä¸**ï¼åäºå¡å¤ç¨æçç»å®æ¹æ¬¡é»è¾ï¼æ£å¼æçç ãæçä¸è¢ç 级èå½å
¥ãåç§ä¸è´æ ¡éªï¼ï¼ä»»ä¸æ¥å¤±è´¥æ´ä½åæ»ã |
| | | - ç¼è¾æ¶ä»
ä¼ æ¬æ¬¡æ°å¢å¾éçæçï¼å·²ç»å®æçä¸å¨ä¸æä¸ï¼unbound-list å·²è¿æ»¤ï¼ï¼ä¸æ¯æè§£ç»ï¼æªå¾é䏿¹ç¶æã䏿ªæåéã |
| | | - æ°æ¥å£ `GET /mes/pro/pallet/unbound-list`ï¼batch_id ä¸ºç©ºãæ æ£å¼æçç 䏿ªä½åºçä¸´æ¶æçã |
| | | - å端èè°ç»åè§ `docs/mes_bag_code_package_refactor_integration.md`ã |
| | | |
| | | ## 9. è¡¥å
éæ±ï¼åå§è¢ç ä¸å表æåºï¼2026-09-17ï¼ |
| | | |
| | | - æ°å¢ `POST /mes/pro/bag-code/raw-generate`ï¼ä»
éåç§+è¢ç æ°éå³çæå¯¹åºæ°éè¢ç ï¼å¸¦åç§åä½ãuuid æç»ï¼ï¼**䏿 ¡éªè®¡éåä½ç±»åãä¸çææç**ï¼åç»å½å
¥æ¹æ¬¡/ç»æç/å°å·/å é¤ä¸æ°æ®å
è¢ç ä¸è´ãèµç 管ç页工å
·æ å ãçæåå§è¢ç ãå¼¹çªå
¥å£ã |
| | | - è¢ç å页æ¥è¯¢æ¹ä¸ºæ**å建æ¶é´ååº**ï¼åç§æç¼å·ååºï¼ï¼åãè¢åºå·ååºãåºå¼ã |
| | | - ç¼è¯ `mvn compile -pl yudao-module-mes -am -q` éè¿ãåç«¯ç±»åæ£æ¥æ¹å¨æä»¶é¶é误ã |
| | | |
| | | ## 10. è¡¥å
éæ±ï¼è¢ç å表åç§æ¥è¯¢ï¼2026-09-17ï¼ |
| | | |
| | | - èµç 管çå表æç´¢åºæ°å¢ãåç§ãæ¡ä»¶ï¼å¤ç¨ `MdmItemSelect` éæ©ç»ä»¶ï¼ï¼æ `mes_pro_bag_code.item_id` çå¼è¿æ»¤ï¼å页ä¸å¯¼åº Excel åå£å¾çæã |
| | | - åå²ç©ºç½è¢ç `item_id` 为空ï¼éæ©åç§åä¸ä¼å½ä¸ï¼å±æ£å¸¸ï¼ã§3.3 åãç¼ç /åç§°å¯æ£ç´¢æ¬æä¸åï¼ä»
å±ç¤ºãå°±æ¤å级为æåç§ç¼å·æ£ç´¢ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ¹æ¬¡ç产管çï¼éè产线ç¼ç ãåæ®µæ¹åãæ°å¢å å·¥çç» - å端èè°æ¹æ¡ |
| | | |
| | | ## èæ¯ |
| | | |
| | | æ¹æ¬¡ç产管ç页é¢ï¼/mes/pro/batchï¼è°æ´ï¼ |
| | | |
| | | - éèã产线ç¼ç ãï¼å表åãæç´¢é¡¹ãExcel 导åºåä¸åå±ç¤ºï¼æ¥å£ä»è¿å `lineCode`ï¼ã |
| | | - ã产线åç§°ãå±ç¤ºææ¡ç»ä¸æ¹ä¸ºãå å·¥åä½ãï¼æ°æ®ä»ä¸º `lineName`ï¼æ¥æºäº§çº¿ä¸»æ°æ®ï¼ã |
| | | - ãè®¡åæ°éãå±ç¤ºææ¡æ¹ä¸ºãå å·¥æ°éãï¼æ°æ®ä»ä¸º `planQuantity`ï¼2026-09-17 ç±ãä»·æ ¼æ°éã忬¡æ´åï¼ã |
| | | - æ°å¢ãå å·¥çç»ãåæ®µï¼æå·¥å¡«åææ¬ï¼æé¿ 64 å符ï¼ä½ç½®å¨ãå å·¥åä½ãä¹åã |
| | | |
| | | ## API åå |
| | | |
| | | | æ¹æ³ | è·¯å¾ | åå | |
| | | |------|------|------| |
| | | | POST | /mes/pro/batch/create | 请æ±ä½æ°å¢ `processingTeam`ï¼å¯éï¼ | |
| | | | PUT | /mes/pro/batch/update | åä¸ | |
| | | | PUT | /mes/pro/batch/fill-info | åä¸ï¼ä¸´æ¶æ¹æ¬¡è¡¥å½ï¼ | |
| | | | GET | /mes/pro/batch/get | ååºæ°å¢ `processingTeam` | |
| | | | GET | /mes/pro/batch/page | ååºæ°å¢ `processingTeam`ï¼æ°å¢æ¥è¯¢åæ° `processingTeam`ï¼æ¨¡ç³å¹é
ï¼ | |
| | | |
| | | **åæ®µè¯´æï¼** |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | processingTeam | String(64) | å¦ | å å·¥çç»ï¼æå·¥å¡«åï¼ä¸é产线ä¹å¯å¡« | |
| | | |
| | | **ååºç¤ºä¾ï¼èéï¼ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "list": [ |
| | | { |
| | | "id": 1, |
| | | "code": "PC20260917L01NY001", |
| | | "lineName": "å
è£
ä¸çº¿", |
| | | "processingTeam": "ä¸å·å å·¥çç»", |
| | | "planQuantity": 1000, |
| | | "ownerUserName": "å¼ ä¸" |
| | | } |
| | | ], |
| | | "total": 1 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | æ°å¢/è¡¥å½/ç¼è¾æ¹æ¬¡ | ãå å·¥çç»ã为å¯éææ¬è¾å
¥ï¼ç¼è¾æ¶ä¸ä¼ ä¸ä¼æ¸
空åå²å¼ | |
| | | | å å·¥åä½ | ä»ç±éæ©äº§çº¿ï¼`lineId`ï¼åå¡« `lineName`ï¼ä»
å±ç¤ºææ¡åå | |
| | | | å å·¥æ°é | ä»
å±ç¤ºææ¡ååï¼åæ®µä¸æ ¡éªé»è¾ä¸å | |
| | | | 产线ç¼ç | æ¥å£ä¿ç `lineCode`ï¼æ«ç ãæ¹æ¬¡å·çæçä»ä¾èµï¼ï¼é¡µé¢ä¸å¯¼åºéè | |
| | | | å¯¼åº Excel | å忥ååï¼å»æã产线ç¼ç ãï¼ã产线åç§°âå å·¥åä½ãï¼æ°å¢ãå å·¥çç»ãï¼ãè®¡åæ°éâå å·¥æ°éã | |
| | | |
| | | ## æ°æ®åºåæ´ |
| | | |
| | | `mes_pro_batch` æ°å¢å `processing_team VARCHAR(64) NULL COMMENT 'å å·¥çç»'`ï¼èæ¬ï¼`docs/sql/pro_batch_processing_team.sql`ï¼ã |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - æ«ç 追溯弹çªï¼qr-trace-modalï¼ãæ¹æ¬¡è¿½æº¯é¡µï¼qc/batchtraceï¼æ¬æ¬¡æªè¦æ±è°æ´ï¼ä»å±ç¤ºäº§çº¿ç¼ç /åç§°ä¸è®¡åæ°éææ¡ï¼å¦éç»ä¸å¦è¡å¤çã |
| | | - æ¬æ¹åç«¯å·²åæ¥ä¿®æ¹å端 `src/views/mes/pro/batch/`ï¼åãæç´¢è¡¨åãç¼è¾è¡¨åï¼ä¸ `src/api/mes/pro/batch/index.ts` ç±»åï¼ä¾å端å¢é夿 ¸ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- æ¹æ¬¡ç产管çï¼æ°å¢ãå å·¥çç»ãåæ®µ |
| | | -- æ§è¡åºï¼mom-thzyï¼localï¼ |
| | | ALTER TABLE mes_pro_batch ADD COLUMN processing_team VARCHAR(64) NULL COMMENT 'å å·¥çç»ï¼æå·¥å¡«åï¼' AFTER line_name; |
| | |
| | | @Schema(description = "åä½åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "个") |
| | | private String name; |
| | | |
| | | @Schema(description = "ç±»åï¼48åå
/100åå
/å¨ï¼", example = "48åå
") |
| | | private String type; |
| | | |
| | | @Schema(description = "æ¯å¦ä¸»åä½", example = "true") |
| | | private Boolean primaryFlag; |
| | | |
| | |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemStatusUpdateReqVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSyncUpdateReqVO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService; |
| | | import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService; |
| | | import cn.iocoder.yudao.module.mdm.service.item.MdmItemBatchConfigService; |
| | | import cn.iocoder.yudao.module.mdm.service.item.MdmItemService; |
| | | import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService; |
| | |
| | | @Resource |
| | | private MesMdItemApi mesMdItemApi; |
| | | |
| | | @Resource |
| | | private MdmItemCategoryService itemCategoryService; |
| | | @Resource |
| | | private MdmUnitMeasureService unitMeasureService; |
| | | @Resource |
| | |
| | | @PreAuthorize("@ss.hasPermission('mdm:item:query')") |
| | | public CommonResult<PageResult<MdmItemRespVO>> getItemPage(@Valid MdmItemPageReqVO pageReqVO) { |
| | | PageResult<MdmItemDO> pageResult = itemService.getItemPage(pageReqVO); |
| | | // å
³èæ¥è¯¢åç±»åç§° |
| | | Map<Long, MdmItemCategoryDO> categoryMap = itemCategoryService.getItemCategoryMap( |
| | | convertSet(pageResult.getList(), MdmItemDO::getCategoryId)); |
| | | // å
³èæ¥è¯¢è®¡éåä½åç§° |
| | | Map<Long, MdmUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap( |
| | | convertSet(pageResult.getList(), MdmItemDO::getUnitMeasureId)); |
| | |
| | | .collect(Collectors.toMap(MesWmWarehouseRespDTO::getId, w -> w)); |
| | | // èµå¼ |
| | | respList.forEach(resp -> { |
| | | // åç±»åç§° |
| | | MdmItemCategoryDO category = categoryMap.get(resp.getCategoryId()); |
| | | if (category != null) { |
| | | resp.setCategoryName(category.getName()); |
| | | } |
| | | MdmUnitMeasureDO unit = unitMap.get(resp.getUnitMeasureId()); |
| | | if (unit != null) { |
| | | resp.setUnitMeasureName(unit.getName()); |
| | |
| | | * å¡«å
ç©æååº VO çå
³èåç§°ï¼åç±»ã主åä½ãè¾
åä½ãä»åºåç§°ï¼ |
| | | */ |
| | | private void enrichItemRespVO(MdmItemRespVO resp) { |
| | | // åç±»åç§° |
| | | if (resp.getCategoryId() != null) { |
| | | MdmItemCategoryDO category = itemCategoryService.getItemCategory(resp.getCategoryId()); |
| | | if (category != null) { |
| | | resp.setCategoryName(category.getName()); |
| | | } |
| | | } |
| | | // 主åä½åç§° |
| | | if (resp.getUnitMeasureId() != null) { |
| | | MdmUnitMeasureDO unit = unitMeasureService.getUnitMeasure(resp.getUnitMeasureId()); |
| | |
| | | @Schema(description = "ç©ææ¡ç ", example = "12345678") |
| | | private String barCode; |
| | | |
| | | @Schema(description = "ç©æåç±»ç¼å·", example = "1") |
| | | private Long categoryId; |
| | | |
| | | @Schema(description = "ç©æç±»å", example = "1") |
| | | private Integer itemType; |
| | | |
| | |
| | | @Schema(description = "è§æ ¼åå·", example = "M8*20") |
| | | private String specification; |
| | | |
| | | @Schema(description = "ç©æåç±»ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long categoryId; |
| | | |
| | | @Schema(description = "ç©æåç±»åç§°", example = "äºéé
ä»¶") |
| | | private String categoryName; |
| | | |
| | | @Schema(description = "计éåä½ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long unitMeasureId; |
| | | |
| | |
| | | |
| | | @Schema(description = "ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "éè´ä»·æ ¼", example = "10.00") |
| | | private BigDecimal purchasePrice; |
| | | |
| | | @Schema(description = "éå®ä»·æ ¼", example = "15.00") |
| | | private BigDecimal salesPrice; |
| | |
| | | @Schema(description = "è§æ ¼åå·", example = "M8*20") |
| | | private String specification; |
| | | |
| | | @Schema(description = "ç©æåç±»ç¼å·ï¼å
³è MES ç©æåç±» mes_md_item_typeï¼", example = "1") |
| | | private Long categoryId; |
| | | |
| | | @Schema(description = "计éåä½ç¼å·", example = "1") |
| | | private Long unitMeasureId; |
| | | |
| | |
| | | |
| | | @Schema(description = "ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "éè´ä»·æ ¼", example = "10.00") |
| | | private BigDecimal purchasePrice; |
| | | |
| | | @Schema(description = "éå®ä»·æ ¼", example = "15.00") |
| | | private BigDecimal salesPrice; |
| | |
| | | package cn.iocoder.yudao.module.mdm.controller.admin.unit.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | |
| | | @Schema(description = "åä½åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "个") |
| | | private String name; |
| | | |
| | | @Schema(description = "ç±»å", requiredMode = Schema.RequiredMode.REQUIRED, example = "48åå
") |
| | | @NotBlank(message = "ç±»åä¸è½ä¸ºç©º") |
| | | private String type; |
| | | |
| | | @Schema(description = "æ¯å¦ä¸»åä½", example = "true") |
| | | private Boolean primaryFlag; |
| | | |
| | |
| | | private String name; |
| | | |
| | | /** |
| | | * ç±»å |
| | | * |
| | | * å¯éå¼ï¼48åå
ã100åå
ãå¨ |
| | | */ |
| | | private String type; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸»åä½ |
| | | */ |
| | | private Boolean primaryFlag; |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemPageReqVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemBatchConfigMapper; |
| | | import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemMapper; |
| | | import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService; |
| | | import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService; |
| | | import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService; |
| | | import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi; |
| | | import cn.iocoder.yudao.module.mes.api.item.MesMdItemTypeApi; |
| | | import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemTypeRespDTO; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.module.mdm.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | |
| | | private MdmItemMapper itemMapper; |
| | | |
| | | @Resource |
| | | private MdmItemCategoryService itemCategoryService; |
| | | @Resource |
| | | private MdmUnitMeasureService unitMeasureService; |
| | | @Resource |
| | | private MdmBrandService brandService; |
| | |
| | | private MesMdItemApi mesMdItemApi; |
| | | @Resource |
| | | private MdmItemBatchConfigMapper itemBatchConfigMapper; |
| | | |
| | | @Resource |
| | | private MesMdItemTypeApi mesMdItemTypeApi; |
| | | |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | /** |
| | | * åæ¥ç©æå° MESï¼åä½/åç±»æ code æ å°ï¼ |
| | | * åæ¥ç©æå° MESï¼å使 code æ å°ï¼ |
| | | * |
| | | * MDM ç unitMeasureId/categoryId ä¸ MES ç unitMeasureId/itemTypeId åå±ä¸¤å¥ä¸»æ°æ®ï¼ |
| | | * è¿éå
å¨ MDM ä¾§è§£æåº codeï¼åäº¤ç± MesMdItemApi å¨ MES ä¾§è§£æä¸ºå¯¹åº idã |
| | | * åç§ç®¡ç已廿ãåç§åç±»ãåæ®µï¼åæ¥ä¸åä¼ é MES ç©æåç±»ï¼item_type_id ç空ï¼å¯å¨ MES 侧补填ï¼ã |
| | | * åæ¥å¤±è´¥å°æåºå¼å¸¸ï¼è§¦åå¤å± @Transactional æ´ä½åæ»ï¼MDM æä½ä¸å¹¶åæ»ï¼ã |
| | | */ |
| | | private void syncItemToMes(MdmItemSaveReqVO reqVO) { |
| | |
| | | } |
| | | unitCode = unitMeasure.getCode(); |
| | | } |
| | | // è§£æåç±» id -> codeï¼ä½¿ç¨ MDM æ¬å°åç±»æå¡ï¼ |
| | | String itemTypeCode = null; |
| | | if (reqVO.getCategoryId() != null) { |
| | | CommonResult<MesMdItemTypeRespDTO> itemType = mesMdItemTypeApi.getItemType(reqVO.getCategoryId()); |
| | | itemTypeCode = itemType.getData().getCode(); |
| | | } |
| | | // ç»è£
忥 DTO |
| | | MesMdItemSyncReqDTO syncReqDTO = new MesMdItemSyncReqDTO(); |
| | | syncReqDTO.setCode(reqVO.getCode()); |
| | |
| | | syncReqDTO.setName(reqVO.getName()); |
| | | syncReqDTO.setSpecification(reqVO.getSpecification()); |
| | | syncReqDTO.setUnitCode(unitCode); |
| | | syncReqDTO.setItemTypeCode(itemTypeCode); |
| | | syncReqDTO.setSafeStockFlag(Boolean.TRUE); // ä¿ç MDM ç minStock/maxStockï¼é¿å
被 MES æ¸
é¶ |
| | | syncReqDTO.setMinStock(reqVO.getMinStock()); |
| | | syncReqDTO.setMaxStock(reqVO.getMaxStock()); |
| | |
| | | } |
| | | } |
| | | |
| | | private void validateCategoryExists(Long categoryId) { |
| | | if (categoryId == null) { |
| | | return; |
| | | } |
| | | // ä½¿ç¨ MDM æ¬å°åç±»æå¡æ ¡éª |
| | | MdmItemCategoryDO category = itemCategoryService.getItemCategory(categoryId); |
| | | if (category == null) { |
| | | throw exception(MDM_ITEM_CATEGORY_NOT_EXISTS); |
| | | } |
| | | } |
| | | |
| | | private void validateUnitMeasureExists(Long unitMeasureId) { |
| | | if (unitMeasureService.getUnitMeasure(unitMeasureId) == null) { |
| | | throw exception(MDM_UNIT_MEASURE_NOT_EXISTS); |
| | |
| | | |
| | | @Override |
| | | public PageResult<MdmItemDO> getItemPage(MdmItemPageReqVO pageReqVO) { |
| | | // æ¥æ¾æ¶ï¼å¦ææ¥æ¾æä¸ªåç±»ç¼å·ï¼åå
å«å®çååç±» |
| | | Set<Long> categoryIds = null; |
| | | if (pageReqVO.getCategoryId() != null) { |
| | | categoryIds = new HashSet<>(); |
| | | categoryIds.add(pageReqVO.getCategoryId()); |
| | | List<cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO> children = |
| | | itemCategoryService.getItemCategoryChildrenList(pageReqVO.getCategoryId()); |
| | | categoryIds.addAll(convertSet(children, cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO::getId)); |
| | | } |
| | | // å页æ¥è¯¢ |
| | | return itemMapper.selectPage(pageReqVO, categoryIds); |
| | | return itemMapper.selectPage(pageReqVO, (Collection<Long>) null); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Schema(description = "计éåä½ç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "PCS") |
| | | private String unitCode; |
| | | |
| | | @Schema(description = "ç©æåç±»ç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "TYPE001") |
| | | private String itemTypeCode; |
| | | |
| | | @Schema(description = "æ¯å¦å¯ç¨å®å
¨åºå", example = "false") |
| | | private Boolean safeStockFlag; |
| | | |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.batchconfig.MesMdItemBatchConfigSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; |
| | | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | * MES ç©æäº§å API å®ç°ç±» |
| | | * |
| | | * ä¾ MDM çæ¨¡ååæ¥ç©æä¸»æ°æ®å° MES 使ç¨ã |
| | | * åä½ãåç±»æ code å¨ MES ä¾§è§£æä¸ºå¯¹åº idã |
| | | * å使 code å¨ MES ä¾§è§£æä¸ºå¯¹åº idã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | |
| | | private MesMdItemService itemService; |
| | | @Resource |
| | | private MesMdItemMapper itemMapper; |
| | | @Resource |
| | | private MesMdItemTypeService itemTypeService; |
| | | @Resource |
| | | private MesMdUnitMeasureService unitMeasureService; |
| | | @Resource |
| | |
| | | } |
| | | |
| | | /** |
| | | * å°åæ¥ DTO 转æ¢ä¸º MES ç©æäº§å SaveReqVOï¼å¹¶æ code è§£æåä½/åç±» id |
| | | * å°åæ¥ DTO 转æ¢ä¸º MES ç©æäº§å SaveReqVOï¼å¹¶æ code è§£æåä½ id |
| | | * |
| | | * MDM åç§ç®¡ç已廿ãåç§åç±»ãï¼åæ¥ä¸åè®¾ç½®ç©æåç±»ï¼item_type_id ç空ï¼å¯å¨ MES ä¾§æå·¥è¡¥å¡«ï¼ |
| | | */ |
| | | private MesMdItemSaveReqVO buildSaveReqVO(MesMdItemSyncReqDTO syncReqDTO) { |
| | | // è§£æè®¡éåä½ code -> id |
| | |
| | | if (unitMeasure == null) { |
| | | throw exception(MD_UNIT_MEASURE_NOT_EXISTS); |
| | | } |
| | | // è§£æç©æåç±» code -> id |
| | | MesMdItemTypeDO itemType = itemTypeService.getItemTypeByCode(syncReqDTO.getItemTypeCode()); |
| | | if (itemType == null) { |
| | | throw exception(MD_ITEM_TYPE_NOT_EXISTS); |
| | | } |
| | | // ç»è£
ï¼code/name/specification/safeStockFlag/minStock/maxStock/highValue/batchFlag/remark ååæ·è´ï¼ |
| | | MesMdItemSaveReqVO saveReqVO = BeanUtils.toBean(syncReqDTO, MesMdItemSaveReqVO.class); |
| | | saveReqVO.setUnitMeasureId(unitMeasure.getId()); |
| | | saveReqVO.setItemTypeId(itemType.getId()); |
| | | return saveReqVO; |
| | | } |
| | | |
| | |
| | | @NotNull(message = "计éåä½ä¸è½ä¸ºç©º") |
| | | private Long unitMeasureId; |
| | | |
| | | @Schema(description = "ç©æåç±»ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "ç©æåç±»ç¼å·ä¸è½ä¸ºç©º") |
| | | @Schema(description = "ç©æåç±»ç¼å·", example = "1") |
| | | private Long itemTypeId; |
| | | |
| | | @Schema(description = "æ¯å¦å¯ç¨å®å
¨åºå", example = "false") |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeRawGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeRespVO; |
| | |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-bag-code:create')") |
| | | public CommonResult<MesProBagCodeGenerateRespVO> generateBagCodes(@Valid @RequestBody MesProBagCodeGenerateReqVO generateReqVO) { |
| | | return success(bagCodeService.generateBagCodes(generateReqVO)); |
| | | } |
| | | |
| | | @PostMapping("/raw-generate") |
| | | @Operation(summary = "çæåå§è¢ç ï¼ä»
éåç§ä¸è¢ç æ°éï¼ä¸å
³è计éåä½ç±»åãä¸çææçï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-bag-code:create')") |
| | | public CommonResult<MesProBagCodeGenerateRespVO> generateRawBagCodes( |
| | | @Valid @RequestBody MesProBagCodeRawGenerateReqVO rawGenerateReqVO) { |
| | | return success(bagCodeService.generateRawBagCodes(rawGenerateReqVO)); |
| | | } |
| | | |
| | | @PostMapping("/replace") |
| | |
| | | .setProduceDate(batch.getProduceDate()) |
| | | .setLineCode(batch.getLineCode()) |
| | | .setLineName(batch.getLineName()) |
| | | .setOwnerUserId(batch.getOwnerUserId()) |
| | | .setItemId(batch.getItemId()); |
| | | .setOwnerUserId(batch.getOwnerUserId()); |
| | | // 责任人 |
| | | if (batch.getOwnerUserId() != null) { |
| | | AdminUserRespDTO user = adminUserApi.getUser(batch.getOwnerUserId()); |
| | |
| | | respVO.setOwnerUserName(user.getNickname()); |
| | | } |
| | | } |
| | | // åç§ä¿¡æ¯ |
| | | if (batch.getItemId() != null) { |
| | | MesMdmItemDO item = mdmItemService.getItem(batch.getItemId()); |
| | | if (item != null) { |
| | | respVO.setItemCode(item.getCode()) |
| | | .setItemName(item.getName()) |
| | | .setItemSpecification(item.getSpecification()); |
| | | } |
| | | } |
| | | // åç§ä¿¡æ¯ï¼ä¼å
åè¢ç ä¸çåç§ï¼æ°æ®å
çææ¶ç»å®ï¼ï¼åå²è¢ç åéæ¹æ¬¡åç§ |
| | | Long itemId = bagCode.getItemId() != null ? bagCode.getItemId() |
| | | : (batch == null ? null : batch.getItemId()); |
| | | if (itemId != null) { |
| | | MesMdmItemDO item = mdmItemService.getItem(itemId); |
| | | if (item != null) { |
| | | respVO.setItemId(itemId) |
| | | .setItemCode(item.getCode()) |
| | | .setItemName(item.getName()) |
| | | .setItemSpecification(item.getSpecification()); |
| | | } |
| | | } |
| | | return respVO; |
| | |
| | | * æå»ºè¢ç äºç»´ç æ ç¾å表ï¼äºç»´ç ç¼ç 纯ç å¼ï¼å¾çå å å
³é®ä¿¡æ¯æåï¼ |
| | | */ |
| | | private List<QrLabelInfo> buildBagCodeQrLabels(List<MesProBagCodeDO> list) { |
| | | // 1. è·å¾å
³èæ°æ®ï¼æ¹æ¬¡ãåç§ãè´£ä»»äººï¼ |
| | | // 1. è·å¾å
³èæ°æ®ï¼æ¹æ¬¡ãåç§ã责任人ï¼ï¼åç§éåå«è¢ç èªèº«åç§ä¸å岿¹æ¬¡åç§ |
| | | Map<Long, MesProBatchDO> batchMap = convertMap( |
| | | batchService.getBatchList(convertSet(list, MesProBagCodeDO::getBatchId)), MesProBatchDO::getId); |
| | | Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap( |
| | | convertSet(batchMap.values(), MesProBatchDO::getItemId)); |
| | | Set<Long> itemIds = convertSet(list, MesProBagCodeDO::getItemId); |
| | | itemIds.addAll(convertSet(batchMap.values(), MesProBatchDO::getItemId)); |
| | | Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(itemIds); |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(batchMap.values(), MesProBatchDO::getOwnerUserId)); |
| | | // 2. æå»ºæ ç¾ |
| | |
| | | @Data |
| | | public class MesProBagCodeGenerateReqVO { |
| | | |
| | | @Schema(description = "çæè¢æ°ï¼æ¬æ¬¡çæçè¢ç æ°éï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| | | @NotNull(message = "çæè¢æ°ä¸è½ä¸ºç©º") |
| | | @Positive(message = "çæè¢æ°å¿
é¡»å¤§äº 0") |
| | | private Integer count; |
| | | @Schema(description = "åç§ï¼ç©æï¼ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "åç§ä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "æçæ°ï¼åç§ä¸»åä½ç±»å为 48åå
/100åå
æ¶å¿
å¡«ï¼è¢ç æ° = æ¯æè¢æ° à æçæ°ï¼", example = "5") |
| | | @Positive(message = "æçæ°å¿
é¡»å¤§äº 0") |
| | | private Integer palletCount; |
| | | |
| | | @Schema(description = "è¢ç æ°ï¼åç§ä¸»åä½ç±»å为 å¨ æ¶å¿
å¡«ï¼ä¸çææçï¼", example = "100") |
| | | @Positive(message = "è¢ç æ°å¿
é¡»å¤§äº 0") |
| | | private Integer bagCount; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES è¢ç çæååº") |
| | | @Data |
| | | public class MesProBagCodeGenerateRespVO { |
| | | |
| | | @Schema(description = "çæç» UUID") |
| | | private String uuid; |
| | | |
| | | @Schema(description = "åç§ä¸»åä½ç±»å", example = "48åå
") |
| | | private String type; |
| | | |
| | | @Schema(description = "æ¯æçè¢æ°ï¼ç±»å为 å¨ æ¶ä¸º 0ï¼", example = "48") |
| | | private Integer perPallet; |
| | | |
| | | @Schema(description = "æ¬æ¬¡çæçè¢ç æ»æ°", example = "240") |
| | | private Integer totalCount; |
| | | |
| | | @Schema(description = "èªå¨çæçæçç¼å·å表ï¼ç±»å为 å¨ æ¶ä¸ºç©ºï¼") |
| | | private List<Long> palletIds; |
| | | } |
| | |
| | | @Schema(description = "ç»å®æçç¼å·", example = "1024") |
| | | private Long palletId; |
| | | |
| | | @Schema(description = "åç§ï¼ç©æï¼ç¼å·", example = "1024") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç¶æï¼åå
¸ mes_pro_bag_code_statusï¼", example = "10") |
| | | private Integer status; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Positive; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - MES åå§è¢ç çæ Request VOï¼ä»
åç§+æ°éï¼ä¸å
³è计éåä½ç±»åãä¸çææçï¼") |
| | | @Data |
| | | public class MesProBagCodeRawGenerateReqVO { |
| | | |
| | | @Schema(description = "åç§ï¼ç©æï¼ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "åç§ä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "è¢ç æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| | | @NotNull(message = "è¢ç æ°éä¸è½ä¸ºç©º") |
| | | @Positive(message = "è¢ç æ°éå¿
é¡»å¤§äº 0") |
| | | private Integer count; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | @ColumnWidth(30) |
| | | private String palletCode; |
| | | |
| | | @Schema(description = "åç§ç¼å·", example = "1") |
| | | @ExcelIgnore |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "åç§ç¼ç ") |
| | | @ExcelProperty("åç§ç¼ç ") |
| | | @ColumnWidth(20) |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "åç§åç§°") |
| | | @ExcelProperty("åç§åç§°") |
| | | @ColumnWidth(20) |
| | | private String itemName; |
| | | |
| | | @Schema(description = "ç¶æï¼åå
¸ mes_pro_bag_code_statusï¼", example = "10") |
| | | @ExcelProperty(value = "ç¶æ", converter = DictConvert.class) |
| | | @DictFormat(DictTypeConstants.MES_PRO_BAG_CODE_STATUS) |
| | |
| | | if (CollUtil.isEmpty(list)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. è·å¾å
³èæ°æ®ï¼è´£ä»»äººãåç§ç©æï¼ |
| | | // 1. è·å¾å
³èæ°æ®ï¼è´£ä»»äººï¼ï¼åç§å·²ä¸æ²å°è¢ç æ°æ®å
ï¼æ¹æ¬¡å表ä¸åå±ç¤º |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(list, MesProBatchDO::getOwnerUserId)); |
| | | Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap( |
| | | convertSet(list, MesProBatchDO::getItemId)); |
| | | // 2. æå»ºç»æ |
| | | return BeanUtils.toBean(list, MesProBatchRespVO.class, vo -> { |
| | | MapUtils.findAndThen(userMap, vo.getOwnerUserId(), user -> |
| | | vo.setOwnerUserName(user.getNickname())); |
| | | MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { |
| | | vo.setItemCode(item.getCode()); |
| | | vo.setItemName(item.getName()); |
| | | vo.setItemSpecification(item.getSpecification()); |
| | | }); |
| | | }); |
| | | return BeanUtils.toBean(list, MesProBatchRespVO.class, vo -> |
| | | MapUtils.findAndThen(userMap, vo.getOwnerUserId(), user -> |
| | | vo.setOwnerUserName(user.getNickname()))); |
| | | } |
| | | |
| | | private List<MesProBatchWorkerRespVO> buildWorkerRespVOList(List<MesProBatchWorkerDO> workers) { |
| | |
| | | @Schema(description = "ä¸´æ¶æ¹æ¬¡ç ", example = "PB-00000001") |
| | | private String tempCode; |
| | | |
| | | @Schema(description = "åç§ï¼äº§åç©æï¼ç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "产线ç¼å·", example = "1") |
| | | private Long lineId; |
| | | |
| | | @Schema(description = "产线ç¼ç ", example = "L01") |
| | | private String lineCode; |
| | | |
| | | @Schema(description = "产线åç§°", example = "å
è£
ä¸çº¿") |
| | | @Schema(description = "产线åç§°ï¼é¡µé¢å±ç¤ºä¸ºãå å·¥åä½ãï¼", example = "å
è£
ä¸çº¿") |
| | | private String lineName; |
| | | |
| | | @Schema(description = "å å·¥çç»", example = "ä¸å·å å·¥çç»") |
| | | private String processingTeam; |
| | | |
| | | @Schema(description = "è´£ä»»äººç¨æ·ç¼å·", example = "1") |
| | | private Long ownerUserId; |
| | | |
| | |
| | | @ExcelIgnore |
| | | private String tempCode; |
| | | |
| | | @Schema(description = "åç§ï¼äº§åç©æï¼ç¼å·", example = "1") |
| | | @ExcelIgnore |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "åç§ç¼ç ") |
| | | @ExcelProperty("åç§ç¼ç ") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "åç§åç§°") |
| | | @ExcelProperty("åç§åç§°") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "åç§è§æ ¼") |
| | | @ExcelProperty("åç§è§æ ¼") |
| | | private String itemSpecification; |
| | | |
| | | @Schema(description = "产线ç¼å·", example = "1") |
| | | @ExcelIgnore |
| | | private Long lineId; |
| | | |
| | | @Schema(description = "产线ç¼ç ", example = "L01") |
| | | @ExcelProperty("产线ç¼ç ") |
| | | @Schema(description = "产线ç¼ç ï¼é¡µé¢å·²éèï¼ä»
æ¥å£è¿åï¼", example = "L01") |
| | | @ExcelIgnore |
| | | private String lineCode; |
| | | |
| | | @Schema(description = "产线åç§°", example = "å
è£
ä¸çº¿") |
| | | @ExcelProperty("产线åç§°") |
| | | @Schema(description = "产线åç§°ï¼é¡µé¢å±ç¤ºä¸ºãå å·¥åä½ãï¼", example = "å
è£
ä¸çº¿") |
| | | @ExcelProperty("å å·¥åä½") |
| | | private String lineName; |
| | | |
| | | @Schema(description = "å å·¥çç»", example = "ä¸å·å å·¥çç»") |
| | | @ExcelProperty("å å·¥çç»") |
| | | private String processingTeam; |
| | | |
| | | @Schema(description = "çäº§æ¥æ") |
| | | @ExcelProperty("çäº§æ¥æ") |
| | | @ColumnWidth(20) |
| | | private LocalDateTime produceDate; |
| | | |
| | | @Schema(description = "è®¡åæ°é", example = "1000") |
| | | @ExcelProperty("è®¡åæ°é") |
| | | @Schema(description = "å å·¥æ°éï¼åè®¡åæ°éï¼é¡µé¢å±ç¤ºä¸ºãå å·¥æ°éãï¼", example = "1000") |
| | | @ExcelProperty("å å·¥æ°é") |
| | | private BigDecimal planQuantity; |
| | | |
| | | @Schema(description = "è´£ä»»äººç¨æ·ç¼å·", example = "1") |
| | |
| | | import jakarta.validation.Valid; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | |
| | | @Schema(description = "ç¼å·", example = "1024") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åç§ï¼äº§åç©æï¼ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "åç§ä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "产线ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "产线ä¸è½ä¸ºç©º") |
| | | @Schema(description = "产线ç¼å·ï¼é¡µé¢å±ç¤ºä¸ºãå å·¥åä½ãï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å å·¥åä½ä¸è½ä¸ºç©º") |
| | | private Long lineId; |
| | | |
| | | @Schema(description = "å å·¥çç»ï¼æå·¥å¡«åï¼", example = "ä¸å·å å·¥çç»") |
| | | @Size(max = 64, message = "å å·¥çç»é¿åº¦ä¸è½è¶
è¿ 64") |
| | | private String processingTeam; |
| | | |
| | | @Schema(description = "çäº§æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "çäº§æ¥æä¸è½ä¸ºç©º") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime produceDate; |
| | | |
| | | @Schema(description = "è®¡åæ°é", example = "1000") |
| | | @Schema(description = "å å·¥æ°éï¼åè®¡åæ°éï¼é¡µé¢å±ç¤ºä¸ºãå å·¥æ°éãï¼", example = "1000") |
| | | private BigDecimal planQuantity; |
| | | |
| | | @Schema(description = "è´£ä»»äººç¨æ·ç¼å·ï¼è´£ä»»è½å®å°äººï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | |
| | | @Valid |
| | | private List<Worker> workers; |
| | | |
| | | @Schema(description = "ç»å®æçç¼å·å表ï¼å¯éï¼ç»å®æ¶æ¹æ¬¡ç´æ¥è¿å
¥ç产ä¸ï¼æçä¸è¢ç 级èå½å
¥æ¬æ¹æ¬¡ï¼æ°å¢/è¡¥å½/ç¼è¾åå¯ä¼ å
¥ï¼ç¼è¾æ¶ä»
éä¼ æ¬æ¬¡æ°å¢å¾éçæçï¼") |
| | | private List<Long> palletIds; |
| | | |
| | | @Schema(description = "ç产人åé
ç½®") |
| | | @Data |
| | | public static class Worker { |
| | |
| | | return success(BeanUtils.toBean(list, MesProPalletRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/unbound-list") |
| | | @Operation(summary = "è·å¾æªç»å®æ¹æ¬¡çä¸´æ¶æçå表ï¼ä¾æ¹æ¬¡æ°å¢/è¡¥å½ç»å®æçä¸æä½¿ç¨ï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-pallet:query')") |
| | | public CommonResult<List<MesProPalletRespVO>> getUnboundPalletList() { |
| | | List<MesProPalletDO> list = palletService.getUnboundPalletList(); |
| | | return success(BeanUtils.toBean(list, MesProPalletRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "å¯¼åºæçç Excel") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-pallet:export')") |
| | |
| | | @Positive(message = "çææ°éå¿
é¡»å¤§äº 0") |
| | | private Integer count; |
| | | |
| | | @Schema(description = "å¯è£
è¢æ°ï¼è¢/æçï¼", example = "25") |
| | | @Positive(message = "å¯è£
è¢æ°å¿
é¡»å¤§äº 0") |
| | | private Integer capacity; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | @Positive(message = "çææ°éå¿
é¡»å¤§äº 0") |
| | | private Integer count; |
| | | |
| | | @Schema(description = "å¯è£
è¢æ°ï¼è¢/æçï¼", example = "25") |
| | | @Positive(message = "å¯è£
è¢æ°å¿
é¡»å¤§äº 0") |
| | | private Integer capacity; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | @ExcelProperty("æçåºå·") |
| | | private Integer palletNo; |
| | | |
| | | @Schema(description = "å¯è£
è¢æ°ï¼è¢/æçï¼", example = "25") |
| | | @ExcelProperty("å¯è£
è¢æ°") |
| | | private Integer capacity; |
| | | |
| | | @Schema(description = "å·²ç»å®è¢ç æ°é", example = "10") |
| | | @ExcelProperty("å·²è£
è¢æ°") |
| | | private Integer bagCount; |
| | |
| | | return "æªç¥"; |
| | | } |
| | | switch (bizType) { |
| | | case MesBizTypeConstants.QC_SEED_QUALITY: |
| | | return "ç§åè´¨æ£"; |
| | | case MesBizTypeConstants.WM_ITEM_RECEIPT_CANCEL: |
| | | return "éè´å
¥åºåæ¶"; |
| | | case MesBizTypeConstants.WM_STOCK_TAKING: |
| | | return "çç¹è°æ´"; |
| | | case MesBizTypeConstants.WM_STOCK_ADJUST_IN: |
| | | return "èªå®ä¹å
¥åº"; |
| | | case MesBizTypeConstants.WM_STOCK_ADJUST_OUT: |
| | |
| | | private String batchCode; |
| | | private Long palletId; |
| | | private String palletCode; |
| | | /** |
| | | * åç§ï¼ç©æï¼ç¼å·ï¼çææ°æ®å
æ¶éå®ï¼å
³è mdm_itemï¼ |
| | | */ |
| | | private Long itemId; |
| | | /** |
| | | * åç§ç¼ç ï¼åä½ï¼ |
| | | */ |
| | | private String itemCode; |
| | | /** |
| | | * åç§åç§°ï¼åä½ï¼ |
| | | */ |
| | | private String itemName; |
| | | private Integer status; |
| | | private Integer qcStatus; |
| | | private LocalDateTime printTime; |
| | |
| | | /** |
| | | * MES çäº§æ¹æ¬¡ DO |
| | | * <p> |
| | | * æ¹æ¬¡ç产管çï¼ä¸è¢ä¸ç 模åï¼ï¼å
³èåç§ï¼MDM ç©æï¼ã产线ï¼äº§çº¿ç»´æ¤ï¼ä¸ç产人åï¼äººåé
ç½®è§ {@link MesProBatchWorkerDO}ï¼ï¼è´£ä»»è½å®å°äººã |
| | | * æ¹æ¬¡å·èªå¨çæï¼ç¼ç è§åå
嫿¥æã产线ç¼ç ãåç§ç¼ç ãæµæ°´å·çè¦ç´ ï¼å¹¶ä¸è¢ç ï¼ä¸è¢ä¸ç ï¼ãæçç èªå¨å
³èã |
| | | * æ¹æ¬¡ç产管çï¼ä¸è¢ä¸ç 模åï¼ï¼å
³è产线ï¼äº§çº¿ç»´æ¤ï¼ä¸ç产人åï¼äººåé
ç½®è§ {@link MesProBatchWorkerDO}ï¼ï¼è´£ä»»è½å®å°äººã |
| | | * åç§å·²ä¸æ²å°è¢ç æ°æ®å
ï¼èµç 管çï¼ï¼æ¹æ¬¡ä¸åç»å®åç§ã |
| | | * æ¹æ¬¡å·èªå¨çæï¼ç¼ç è§åå
嫿¥æã产线ç¼ç ãæµæ°´å·çè¦ç´ ï¼å¹¶ä¸è¢ç ï¼ä¸è¢ä¸ç ï¼ãæçç èªå¨å
³èã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * æ¹æ¬¡å·ï¼èªå¨çæï¼åç¼ + æ¥æ + 产线ç¼ç + åç§ç¼ç + æµæ°´å·ï¼è¡¥å½ä¸å¡ä¿¡æ¯åçæï¼ |
| | | * æ¹æ¬¡å·ï¼èªå¨çæï¼åç¼ + æ¥æ + 产线ç¼ç + æµæ°´å·ï¼è¡¥å½ä¸å¡ä¿¡æ¯åçæï¼ |
| | | */ |
| | | private String code; |
| | | /** |
| | |
| | | */ |
| | | private String tempCode; |
| | | /** |
| | | * åç§ï¼äº§åç©æï¼ç¼å· |
| | | * åç§ï¼äº§åç©æï¼ç¼å·ï¼å·²åºå¼ï¼ |
| | | * <p> |
| | | * å
³è {@link cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO#getId()} |
| | | * <p> |
| | | * åç§å·²ä¸æ²å°è¢ç æ°æ®å
ï¼{@code mes_pro_bag_code.item_id}ï¼ï¼æ°æ¹æ¬¡ä¸ååå
¥ï¼ä»
ä¿çä¾å岿¹æ¬¡è¿½æº¯åé |
| | | */ |
| | | private Long itemId; |
| | | /** |
| | |
| | | */ |
| | | private String lineCode; |
| | | /** |
| | | * 产线åç§°ï¼åä½åï¼ç± {@link #lineId} åå¡«ï¼ |
| | | * 产线åç§°ï¼åä½åï¼ç± {@link #lineId} åå¡«ï¼é¡µé¢å±ç¤ºä¸ºãå å·¥åä½ãï¼ |
| | | */ |
| | | private String lineName; |
| | | /** |
| | | * å å·¥çç»ï¼æå·¥å¡«åï¼ |
| | | */ |
| | | private String processingTeam; |
| | | /** |
| | | * çäº§æ¥æ |
| | | */ |
| | | private LocalDateTime produceDate; |
| | |
| | | .likeIfPresent(MesProBagCodeDO::getBatchCode, reqVO.getBatchCode()) |
| | | .eqIfPresent(MesProBagCodeDO::getUuid, reqVO.getUuid()) |
| | | .eqIfPresent(MesProBagCodeDO::getPalletId, reqVO.getPalletId()) |
| | | .eqIfPresent(MesProBagCodeDO::getItemId, reqVO.getItemId()) |
| | | .eqIfPresent(MesProBagCodeDO::getStatus, reqVO.getStatus()) |
| | | .betweenIfPresent(MesProBagCodeDO::getCreateTime, reqVO.getCreateTime()) |
| | | .orderByAsc(MesProBagCodeDO::getBagNo)); |
| | | .orderByDesc(MesProBagCodeDO::getCreateTime) |
| | | .orderByDesc(MesProBagCodeDO::getId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | .set(MesProBagCodeDO::getPalletId, palletId) |
| | | .set(MesProBagCodeDO::getPalletCode, palletCode) |
| | | .in(MesProBagCodeDO::getId, ids)); |
| | | } |
| | | |
| | | /** |
| | | * æçæ£å¼ç çæåï¼ååå
¶ä¸ææè¢ç çå使çç |
| | | * |
| | | * @param palletId æçç¼å· |
| | | * @param palletCode æ£å¼æçç |
| | | */ |
| | | default void updatePalletCodeByPalletId(Long palletId, String palletCode) { |
| | | update(null, new LambdaUpdateWrapper<MesProBagCodeDO>() |
| | | .set(MesProBagCodeDO::getPalletCode, palletCode) |
| | | .eq(MesProBagCodeDO::getPalletId, palletId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | Integer selectMaxBagNo(); |
| | | |
| | | @Update("<script>UPDATE mes_pro_bag_code SET batch_id = #{batchId}, batch_code = #{batchCode}, update_time = NOW() " + |
| | | "WHERE deleted = 0 AND batch_id IS NULL AND status = #{status} AND id IN " + |
| | | "WHERE deleted = 0 AND batch_id IS NULL AND status IN " + |
| | | "<foreach collection='statuses' item='st' open='(' separator=',' close=')'>#{st}</foreach> AND id IN " + |
| | | "<foreach collection='ids' item='id' open='(' separator=',' close=')'>#{id}</foreach></script>") |
| | | int bindBatchByIds(@Param("ids") Collection<Long> ids, @Param("batchId") Long batchId, |
| | | @Param("batchCode") String batchCode, @Param("status") Integer status); |
| | | @Param("batchCode") String batchCode, @Param("statuses") Collection<Integer> statuses); |
| | | |
| | | /** æ¥è¯¢æçä¸å°æªç»å®æ¹æ¬¡çè¢ç ï¼æçç»å®æ¹æ¬¡æ¶çº§èå½å
¥ç¨ï¼ */ |
| | | default List<MesProBagCodeDO> selectUnboundListByPalletIds(Collection<Long> palletIds) { |
| | | return selectList(new LambdaQueryWrapperX<MesProBagCodeDO>() |
| | | .in(MesProBagCodeDO::getPalletId, palletIds) |
| | | .isNull(MesProBagCodeDO::getBatchId) |
| | | .orderByAsc(MesProBagCodeDO::getId)); |
| | | } |
| | | |
| | | /** æ¹æ¬¡å
ææè¢ç çåç§ç¼å·éåï¼å¿½ç¥åå²ç©ºåç§è¢ç ï¼ï¼ç¨äºå½å
¥æ¹æ¬¡æ¶çåç§ä¸è´æ§æ ¡éª */ |
| | | @Select("SELECT DISTINCT item_id FROM mes_pro_bag_code " + |
| | | "WHERE deleted = 0 AND status <> 30 AND batch_id = #{batchId} AND item_id IS NOT NULL") |
| | | List<Long> selectDistinctItemIdsByBatchId(@Param("batchId") Long batchId); |
| | | |
| | | default List<MesProBagCodeDO> selectListByIdsForUpdate(Collection<Long> ids) { |
| | | return selectList(new LambdaQueryWrapperX<MesProBagCodeDO>() |
| | |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesProBatchDO>() |
| | | .likeIfPresent(MesProBatchDO::getCode, reqVO.getCode()) |
| | | .likeIfPresent(MesProBatchDO::getTempCode, reqVO.getTempCode()) |
| | | .eqIfPresent(MesProBatchDO::getItemId, reqVO.getItemId()) |
| | | .eqIfPresent(MesProBatchDO::getLineId, reqVO.getLineId()) |
| | | .likeIfPresent(MesProBatchDO::getLineCode, reqVO.getLineCode()) |
| | | .likeIfPresent(MesProBatchDO::getLineName, reqVO.getLineName()) |
| | | .likeIfPresent(MesProBatchDO::getProcessingTeam, reqVO.getProcessingTeam()) |
| | | .eqIfPresent(MesProBatchDO::getOwnerUserId, reqVO.getOwnerUserId()) |
| | | .eqIfPresent(MesProBatchDO::getStatus, reqVO.getStatus()) |
| | | .betweenIfPresent(MesProBatchDO::getProduceDate, reqVO.getProduceDate()) |
| | |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProPalletStatusEnum; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.apache.ibatis.annotations.Select; |
| | |
| | | return selectList(MesProPalletDO::getBatchId, batchId); |
| | | } |
| | | |
| | | /** æ¥è¯¢æªç»å®çäº§æ¹æ¬¡çä¸´æ¶æçï¼æ æ£å¼æçç 䏿ªä½åºï¼ï¼ä¾æ¹æ¬¡æ°å¢/è¡¥å½ç»å®æçä¸æä½¿ç¨ */ |
| | | default List<MesProPalletDO> selectUnboundList() { |
| | | return selectList(new LambdaQueryWrapperX<MesProPalletDO>() |
| | | .isNull(MesProPalletDO::getBatchId) |
| | | .isNull(MesProPalletDO::getCode) |
| | | .eq(MesProPalletDO::getStatus, MesProPalletStatusEnum.IN_USE.getStatus()) |
| | | .orderByAsc(MesProPalletDO::getId)); |
| | | } |
| | | |
| | | default PageResult<MesProPalletDO> selectPage(MesProPalletPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesProPalletDO>() |
| | | .likeIfPresent(MesProPalletDO::getCode, reqVO.getCode()) |
| | |
| | | ErrorCode PRO_BAG_CODE_BIND_PALLET_MISMATCH = new ErrorCode(1_040_752_003, "è¢ç 䏿çä¸å±äºåä¸çäº§æ¹æ¬¡ï¼ä¸å
许ç»å®"); |
| | | ErrorCode PRO_BAG_CODE_BIND_PALLET_BOUND = new ErrorCode(1_040_752_004, "åå¨å·²ç»å®æççè¢ç ï¼è¯·å
è§£ç»"); |
| | | ErrorCode PRO_BAG_CODE_UUID_NOT_EXISTS = new ErrorCode(1_040_752_005, "è¢ç çæç»ä¸åå¨"); |
| | | ErrorCode PRO_BAG_CODE_BIND_PALLET_OVER_CAPACITY = new ErrorCode(1_040_752_006, "ç»å®åè¢ç æ°éè¶
è¿æçå¯è£
è¢æ°"); |
| | | ErrorCode PRO_BAG_CODE_REPLACE_BATCH_STATUS_INVALID = new ErrorCode(1_040_752_007, "çäº§æ¹æ¬¡ç¶æä¸å
è®¸ç ´æè¢ç æ¿æ¢"); |
| | | ErrorCode PRO_BAG_CODE_REPLACE_BATCH_MISMATCH = new ErrorCode(1_040_752_008, "å¾
æ¿æ¢è¢ç ä¸å±äºæå®çäº§æ¹æ¬¡"); |
| | | ErrorCode PRO_BAG_CODE_REPLACE_ALREADY_REPLACED = new ErrorCode(1_040_752_009, "è¢ç å·²å®ææ¿æ¢ï¼ä¸å
许é夿¿æ¢"); |
| | | ErrorCode PRO_BAG_CODE_REPLACE_STATUS_INVALID = new ErrorCode(1_040_752_010, "è¢ç ç¶æä¸å
è®¸ç ´ææ¿æ¢"); |
| | | ErrorCode PRO_BAG_CODE_REPLACE_PALLET_INVALID = new ErrorCode(1_040_752_011, "è¢ç åæçä¸å卿已ä½åºï¼ä¸å
许继æ¿"); |
| | | ErrorCode PRO_BAG_CODE_ITEM_TYPE_NOT_CONFIGURED = new ErrorCode(1_040_752_012, "åç§ä¸»è®¡éå使ªé
置类åï¼ä»
æ¯æ 48åå
/100åå
/å¨"); |
| | | ErrorCode PRO_BAG_CODE_PALLET_COUNT_REQUIRED = new ErrorCode(1_040_752_013, "该åç§ææççæè¢ç ï¼æçæ°å¿
é¡»å¤§äº 0"); |
| | | ErrorCode PRO_BAG_CODE_BIND_BATCH_ITEM_MISMATCH = new ErrorCode(1_040_752_014, "å½å
¥æ¹æ¬¡çè¢ç å¿
é¡»å±äºåä¸åç§"); |
| | | |
| | | // ========== MES ç产管ç-æçç ï¼1-040-753-000ï¼ ========== |
| | | ErrorCode PRO_PALLET_NOT_EXISTS = new ErrorCode(1_040_753_000, "æçç ä¸åå¨"); |
| | |
| | | if (StrUtil.isNotEmpty(bagCode.getPalletCode())) { |
| | | keyValues.put("ç»å®æç", bagCode.getPalletCode()); |
| | | } |
| | | // åç§ä¼å
åè¢ç èªèº«ï¼æ°æ®å
çææ¶ç»å®ï¼æªå½æ¹æ¬¡ä¹å¯æå°ï¼ï¼åå²è¢ç åéæ¹æ¬¡åç§ |
| | | if (StrUtil.isNotEmpty(bagCode.getItemName())) { |
| | | keyValues.put("åç§", bagCode.getItemName()); |
| | | } |
| | | if (batch != null) { |
| | | fillBatchKeyValues(keyValues, batch, itemMap, userMap); |
| | | } |
| | |
| | | validateItemCodeUnique(reqVO.getId(), reqVO.getCode()); |
| | | // æ ¡éªç©æåç§°çå¯ä¸æ§ |
| | | validateItemNameUnique(reqVO.getId(), reqVO.getName()); |
| | | // æ ¡éªç©æåç±»åå¨ |
| | | validateItemTypeExists(reqVO.getItemTypeId()); |
| | | // æ ¡éªç©æåç±»åå¨ï¼MDM åç§åæ¥ä¸ä¼ åç±»ï¼å
è®¸ä¸ºç©ºï¼ |
| | | if (reqVO.getItemTypeId() != null) { |
| | | validateItemTypeExists(reqVO.getItemTypeId()); |
| | | } |
| | | // æ ¡éªè®¡éåä½åå¨ |
| | | validateUnitMeasureExists(reqVO.getUnitMeasureId()); |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeRawGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; |
| | |
| | | */ |
| | | MesProBagCodeGenerateRespVO generateBagCodes(@Valid MesProBagCodeGenerateReqVO generateReqVO); |
| | | |
| | | /** |
| | | * çæåå§è¢ç ï¼ä»
éåç§+è¢ç æ°éï¼ä¸æ ¡éªè®¡éåä½ç±»åãä¸çææçï¼ |
| | | * è¢ç 带åç§åä½ï¼åç»å¯æ£å¸¸å½å
¥æ¹æ¬¡/ç»å®æç |
| | | * |
| | | * @param rawGenerateReqVO çæä¿¡æ¯ |
| | | * @return çæç» UUID 䏿°éï¼type/perPallet/palletIds ä¸ºç©ºï¼ |
| | | */ |
| | | MesProBagCodeGenerateRespVO generateRawBagCodes(@Valid MesProBagCodeRawGenerateReqVO rawGenerateReqVO); |
| | | |
| | | void bindBatch(@Valid MesProBagCodeBindBatchReqVO bindReqVO); |
| | | |
| | | /** |
| | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeBindBatchReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeBindReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeRawGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceItemRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeReplaceDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO; |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProBagCodeStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProBatchStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProPalletStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | |
| | | @Resource |
| | | private MesProPalletService palletService; |
| | | @Resource |
| | | private MesMdmItemService mdmItemService; |
| | | @Resource |
| | | private MdmUnitMeasureApi unitMeasureApi; |
| | | |
| | | /** |
| | | * 计éåä½ç±»åãå¨ãï¼æ æç模å¼ï¼ |
| | | */ |
| | | private static final String UNIT_TYPE_TON = "å¨"; |
| | | /** |
| | | * 计éåä½ç±»åãNåå
ãï¼æ¯æçè£
N 个è¢ç |
| | | */ |
| | | private static final Pattern KG_TYPE_PATTERN = Pattern.compile("^(\\d{1,5})åå
$"); |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesProBagCodeGenerateRespVO generateBagCodes(MesProBagCodeGenerateReqVO generateReqVO) { |
| | | if (generateReqVO.getCount() == null || generateReqVO.getCount() <= 0) { |
| | | throw exception(PRO_BAG_CODE_GENERATE_COUNT_INVALID); |
| | | // 1. æ ¡éªåç§å¹¶è¯»å主计éåä½ç±»å |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(generateReqVO.getItemId()); |
| | | String type = getUnitType(item); |
| | | |
| | | // 2. æç±»åæ¢ç®è¢ç æ°éï¼Nåå
= æ¯æ N è¢ Ã æçæ°ï¼å¨ = ç´æ¥è¾å
¥è¢ç æ°ï¼æ æçï¼ |
| | | boolean ton = UNIT_TYPE_TON.equals(type); |
| | | int perPallet = ton ? 0 : parseKgPerPallet(type); |
| | | int totalCount; |
| | | int palletCount = 0; |
| | | if (ton) { |
| | | if (generateReqVO.getBagCount() == null || generateReqVO.getBagCount() <= 0) { |
| | | throw exception(PRO_BAG_CODE_GENERATE_COUNT_INVALID); |
| | | } |
| | | totalCount = generateReqVO.getBagCount(); |
| | | } else { |
| | | if (generateReqVO.getPalletCount() == null || generateReqVO.getPalletCount() <= 0) { |
| | | throw exception(PRO_BAG_CODE_PALLET_COUNT_REQUIRED); |
| | | } |
| | | palletCount = generateReqVO.getPalletCount(); |
| | | totalCount = perPallet * palletCount; |
| | | } |
| | | |
| | | // çæé¶æ®µåªå建å
¨å±å¯ä¸è¢ç ï¼çäº§æ¹æ¬¡å¨åç»å½å
¥ |
| | | int startNo = bagCodeMapper.selectMaxBagNo() + 1; |
| | | // 3. çæé¶æ®µï¼è¢ç ç´æ¥ç»å®åç§ï¼çäº§æ¹æ¬¡å¨åç»å½å
¥ |
| | | String uuid = IdUtil.fastSimpleUUID(); |
| | | List<MesProPalletDO> pallets = new ArrayList<>(palletCount); |
| | | if (!ton) { |
| | | int startSeq = palletMapper.selectMaxTempCodeSeq() + 1; |
| | | for (int i = 0; i < palletCount; i++) { |
| | | pallets.add(new MesProPalletDO() |
| | | .setTempCode("PL-" + StrUtil.padPre(String.valueOf(startSeq + i), 8, '0')) |
| | | .setBagCount(perPallet) |
| | | .setAutoGenerated(true) |
| | | .setStatus(MesProPalletStatusEnum.IN_USE.getStatus())); |
| | | } |
| | | palletMapper.insertBatch(pallets); |
| | | } |
| | | int startNo = bagCodeMapper.selectMaxBagNo() + 1; |
| | | List<MesProBagCodeDO> bagCodes = new ArrayList<>(totalCount); |
| | | for (int i = 0; i < totalCount; i++) { |
| | | int bagNo = startNo + i; |
| | | MesProPalletDO pallet = ton ? null : pallets.get(i / perPallet); |
| | | bagCodes.add(new MesProBagCodeDO() |
| | | .setUuid(uuid) |
| | | .setCode("BAG-" + StrUtil.padPre(String.valueOf(bagNo), 8, '0')) |
| | | .setBagNo(bagNo) |
| | | .setItemId(item.getId()) |
| | | .setItemCode(item.getCode()) |
| | | .setItemName(item.getName()) |
| | | .setPalletId(pallet == null ? null : pallet.getId()) |
| | | .setPalletCode(pallet == null ? null : pallet.getTempCode()) |
| | | .setStatus(MesProBagCodeStatusEnum.GENERATED.getStatus()) |
| | | .setRemark(generateReqVO.getRemark())); |
| | | } |
| | | bagCodeMapper.insertBatch(bagCodes); |
| | | return new MesProBagCodeGenerateRespVO() |
| | | .setUuid(uuid) |
| | | .setType(type) |
| | | .setPerPallet(perPallet) |
| | | .setTotalCount(totalCount) |
| | | .setPalletIds(pallets.stream().map(MesProPalletDO::getId).toList()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesProBagCodeGenerateRespVO generateRawBagCodes(MesProBagCodeRawGenerateReqVO generateReqVO) { |
| | | // åå§è¢ç ä¸ä¾èµè®¡éåä½ç±»å䏿çï¼ä»
ææ°éçæï¼è¢ç 带åç§åä½ï¼åç»å¯æ£å¸¸å½å
¥æ¹æ¬¡/ç»å®æç |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(generateReqVO.getItemId()); |
| | | String uuid = IdUtil.fastSimpleUUID(); |
| | | int startNo = bagCodeMapper.selectMaxBagNo() + 1; |
| | | List<MesProBagCodeDO> bagCodes = new ArrayList<>(generateReqVO.getCount()); |
| | | for (int i = 0; i < generateReqVO.getCount(); i++) { |
| | | int bagNo = startNo + i; |
| | |
| | | .setUuid(uuid) |
| | | .setCode("BAG-" + StrUtil.padPre(String.valueOf(bagNo), 8, '0')) |
| | | .setBagNo(bagNo) |
| | | .setItemId(item.getId()) |
| | | .setItemCode(item.getCode()) |
| | | .setItemName(item.getName()) |
| | | .setStatus(MesProBagCodeStatusEnum.GENERATED.getStatus()) |
| | | .setRemark(generateReqVO.getRemark())); |
| | | } |
| | | bagCodeMapper.insertBatch(bagCodes); |
| | | return new MesProBagCodeGenerateRespVO().setUuid(uuid); |
| | | return new MesProBagCodeGenerateRespVO() |
| | | .setUuid(uuid) |
| | | .setTotalCount(bagCodes.size()) |
| | | .setPalletIds(List.of()); |
| | | } |
| | | |
| | | /** |
| | | * 读ååç§ä¸»è®¡éåä½çç±»åï¼48åå
/100åå
/å¨ï¼ï¼æªé
ç½®ææ æ³è¯å«æ¶æ¥é |
| | | */ |
| | | private String getUnitType(MesMdmItemDO item) { |
| | | String type = null; |
| | | if (item.getUnitMeasureId() != null) { |
| | | CommonResult<MdmUnitMeasureRespDTO> result = unitMeasureApi.getUnitMeasure(item.getUnitMeasureId()); |
| | | if (result != null && result.isSuccess() && result.getData() != null) { |
| | | type = StrUtil.trimToNull(result.getData().getType()); |
| | | } |
| | | } |
| | | if (type == null) { |
| | | throw exception(PRO_BAG_CODE_ITEM_TYPE_NOT_CONFIGURED); |
| | | } |
| | | if (!UNIT_TYPE_TON.equals(type) && !KG_TYPE_PATTERN.matcher(type).matches()) { |
| | | throw exception(PRO_BAG_CODE_ITEM_TYPE_NOT_CONFIGURED); |
| | | } |
| | | return type; |
| | | } |
| | | |
| | | /** |
| | | * è§£æãNåå
ãç±»åå¾åºæ¯æçè¢æ° |
| | | */ |
| | | private int parseKgPerPallet(String type) { |
| | | Matcher matcher = KG_TYPE_PATTERN.matcher(type); |
| | | if (!matcher.matches()) { |
| | | throw exception(PRO_BAG_CODE_ITEM_TYPE_NOT_CONFIGURED); |
| | | } |
| | | return Integer.parseInt(matcher.group(1)); |
| | | } |
| | | |
| | | @Override |
| | |
| | | List<Long> ids = bindReqVO.getIds().stream().distinct().toList(); |
| | | List<MesProBagCodeDO> bagCodes = bagCodeMapper.selectListByIdsForUpdate(ids); |
| | | if (bagCodes.size() != ids.size() || bagCodes.stream().anyMatch(code -> |
| | | code.getBatchId() != null || !MesProBagCodeStatusEnum.GENERATED.getStatus().equals(code.getStatus()))) { |
| | | code.getBatchId() != null |
| | | || (!MesProBagCodeStatusEnum.GENERATED.getStatus().equals(code.getStatus()) |
| | | && !MesProBagCodeStatusEnum.PRINTED.getStatus().equals(code.getStatus())))) { |
| | | throw exception(PRO_BAG_CODE_STATUS_NOT_GENERATED); |
| | | } |
| | | // å½å
¥çè¢ç å¿
é¡»å±äºåä¸åç§ï¼ä¸ä¸æ¹æ¬¡å·²æè¢ç åç§ä¸è´ï¼åå²ç©ºç½è¢ç item 为空ä¸å䏿 ¡éªï¼ |
| | | Set<Long> itemIds = new LinkedHashSet<>(); |
| | | bagCodes.stream().map(MesProBagCodeDO::getItemId).filter(Objects::nonNull).forEach(itemIds::add); |
| | | itemIds.addAll(bagCodeMapper.selectDistinctItemIdsByBatchId(batch.getId())); |
| | | if (itemIds.size() > 1) { |
| | | throw exception(PRO_BAG_CODE_BIND_BATCH_ITEM_MISMATCH); |
| | | } |
| | | if (bagCodeMapper.bindBatchByIds(ids, batch.getId(), batch.getCode(), |
| | | MesProBagCodeStatusEnum.GENERATED.getStatus()) != ids.size()) { |
| | | List.of(MesProBagCodeStatusEnum.GENERATED.getStatus(), |
| | | MesProBagCodeStatusEnum.PRINTED.getStatus())) != ids.size()) { |
| | | throw exception(PRO_BAG_CODE_STATUS_NOT_GENERATED); |
| | | } |
| | | batchMapper.updateById(new MesProBatchDO().setId(batch.getId()) |
| | | .setBagQuantity(bagCodeMapper.selectEffectiveCountByBatchId(batch.getId()))); |
| | | // 级èï¼æ¬ç»è¢ç ç»å®çæªå
¥æ¹æ¬¡æçï¼åé
æ£å¼æçç å¹¶ç»å®æ¹æ¬¡ |
| | | bindPalletsToBatch(bagCodes, batch); |
| | | } |
| | | |
| | | /** |
| | | * è¢ç å½å
¥æ¹æ¬¡æ¶ï¼å°å
¶ç»å®çä¸´æ¶æçï¼æªç»å®æ¹æ¬¡ï¼çº§èç»å®å°å䏿¹æ¬¡ï¼ |
| | | * åé
æ£å¼æçç ï¼æ¹æ¬¡å·-Påºå·ï¼ãååè¢ç ä¸çå使çç ãç´¯è®¡æ¹æ¬¡æçæ° |
| | | */ |
| | | private void bindPalletsToBatch(List<MesProBagCodeDO> bagCodes, MesProBatchDO batch) { |
| | | List<Long> palletIds = bagCodes.stream().map(MesProBagCodeDO::getPalletId) |
| | | .filter(Objects::nonNull).distinct().sorted().toList(); |
| | | if (palletIds.isEmpty()) { |
| | | return; |
| | | } |
| | | int nextPalletNo = palletMapper.selectMaxPalletNo(batch.getId()) + 1; |
| | | int boundCount = 0; |
| | | for (Long palletId : palletIds) { |
| | | MesProPalletDO pallet = palletMapper.selectByIdForUpdate(palletId); |
| | | if (pallet == null || pallet.getBatchId() != null || StrUtil.isNotEmpty(pallet.getCode())) { |
| | | continue; |
| | | } |
| | | String palletCode = batch.getCode() + "-P" + StrUtil.padPre(String.valueOf(nextPalletNo++), 2, '0'); |
| | | palletMapper.updateById(new MesProPalletDO().setId(palletId) |
| | | .setCode(palletCode) |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setPalletNo(nextPalletNo - 1)); |
| | | // è¢ç ä¸çå使çç ç±ä¸´æ¶ç æ´æ°ä¸ºæ£å¼ç |
| | | bagCodeMapper.updatePalletCodeByPalletId(palletId, palletCode); |
| | | boundCount++; |
| | | } |
| | | if (boundCount > 0) { |
| | | batchMapper.updateById(new MesProBatchDO().setId(batch.getId()) |
| | | .setPalletQuantity((batch.getPalletQuantity() == null ? 0 : batch.getPalletQuantity()) + boundCount)); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | .setBagNo(newBagNo) |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setItemId(oldBagCode.getItemId()) |
| | | .setItemCode(oldBagCode.getItemCode()) |
| | | .setItemName(oldBagCode.getItemName()) |
| | | .setPalletId(pallet == null ? null : pallet.getId()) |
| | | .setPalletCode(pallet == null ? null : pallet.getCode()) |
| | | .setStatus(MesProBagCodeStatusEnum.GENERATED.getStatus()) |
| | |
| | | if (CollUtil.isEmpty(bagCodes)) { |
| | | throw exception(PRO_BAG_CODE_UUID_NOT_EXISTS); |
| | | } |
| | | // 2. æ ¡éªå为已çæç¶æä¸æªç»å®æç |
| | | // 2. æ ¡éªå为已çæç¶æ |
| | | if (bagCodes.stream().anyMatch(bagCode -> |
| | | !MesProBagCodeStatusEnum.GENERATED.getStatus().equals(bagCode.getStatus()))) { |
| | | throw exception(PRO_BAG_CODE_STATUS_NOT_GENERATED); |
| | | } |
| | | if (bagCodes.stream().anyMatch(bagCode -> bagCode.getPalletId() != null)) { |
| | | throw exception(PRO_BAG_CODE_BIND_PALLET_BOUND); |
| | | // 3. ç»å®çæçä»
é"èªå¨çæä¸æªç»å®æ¹æ¬¡"ï¼çææ°æ®å
æ¶èªå¨ç»å®ï¼ï¼çº§èå é¤ï¼å·²å
¥æ¹æ¬¡çæçä¸å
许éå
å é¤ |
| | | Set<Long> palletIds = new LinkedHashSet<>(); |
| | | bagCodes.stream().map(MesProBagCodeDO::getPalletId).filter(Objects::nonNull).forEach(palletIds::add); |
| | | for (Long palletId : palletIds) { |
| | | MesProPalletDO pallet = palletMapper.selectById(palletId); |
| | | if (pallet != null && (pallet.getBatchId() != null || StrUtil.isNotEmpty(pallet.getCode()))) { |
| | | throw exception(PRO_BAG_CODE_BIND_PALLET_BOUND); |
| | | } |
| | | } |
| | | // 3. å é¤çæç» |
| | | // 4. å é¤çæç»ä¸å
¶èªå¨çæçä¸´æ¶æç |
| | | bagCodeMapper.deleteByIds(bagCodes.stream().map(MesProBagCodeDO::getId).toList()); |
| | | // 4. ååæ¹æ¬¡è¢ç æ°é |
| | | if (!palletIds.isEmpty()) { |
| | | palletMapper.deleteByIds(palletIds); |
| | | } |
| | | // 5. ååæ¹æ¬¡è¢ç æ°é |
| | | MesProBatchDO batch = batchMapper.selectById(bagCodes.get(0).getBatchId()); |
| | | if (batch != null && batch.getBagQuantity() != null) { |
| | | batchMapper.updateById(new MesProBatchDO().setId(batch.getId()) |
| | |
| | | } |
| | | // 2. éå®å¹¶æ ¡éªè¢ç |
| | | List<MesProBagCodeDO> bagCodes = validateBagCodesForBind(bindReqVO.getIds(), pallet, true); |
| | | // 3. æ ¡éªä¸è¶
è¿æçå¯è£
è¢æ° |
| | | // 3. ç»å®è¢ç å¹¶ç´¯å æçå·²è£
è¢æ°ï¼æçæ 容éä¸éï¼ |
| | | int currentCount = pallet.getBagCount() == null ? 0 : pallet.getBagCount(); |
| | | if (pallet.getCapacity() != null && pallet.getCapacity() > 0 |
| | | && currentCount + bagCodes.size() > pallet.getCapacity()) { |
| | | throw exception(PRO_BAG_CODE_BIND_PALLET_OVER_CAPACITY); |
| | | } |
| | | // 4. ç»å®è¢ç å¹¶ç´¯å æçå·²è£
è¢æ° |
| | | bagCodeMapper.bindPalletByIds(bindReqVO.getIds(), pallet.getId(), pallet.getCode()); |
| | | palletService.updatePalletBagCount(pallet.getId(), currentCount + bagCodes.size()); |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchPreGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletBindBatchReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchWorkerDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.line.MesProLineDO; |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProBatchStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.line.MesProLineService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletService; |
| | | import cn.iocoder.yudao.module.mes.service.trace.integrity.MesTraceIntegrityService; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import jakarta.annotation.Resource; |
| | |
| | | private MesProPalletMapper palletMapper; |
| | | |
| | | @Resource |
| | | private MesProPalletService palletService; |
| | | |
| | | @Resource |
| | | private MesMdAutoCodeRecordService autoCodeRecordService; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private MesMdmItemService mdmItemService; |
| | | @Resource |
| | | private MesProLineService lineService; |
| | | @Resource |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createBatch(MesProBatchSaveReqVO createReqVO) { |
| | | // 1. æ ¡éªå
³èæ°æ®ï¼åç§ã产线ãç产人åï¼ |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(createReqVO.getItemId()); |
| | | // 1. æ ¡éªå
³èæ°æ®ï¼äº§çº¿ãç产人åï¼ |
| | | MesProLineDO line = lineService.validateLineExistsAndEnable(createReqVO.getLineId()); |
| | | validateRelations(createReqVO); |
| | | |
| | | // 2. çææ¹æ¬¡å·ï¼ç¼ç è§åï¼åç¼ + æ¥æ + 产线ç¼ç + åç§ç¼ç + æµæ°´å·ï¼ |
| | | String code = generateBatchCode(line.getCode(), item.getCode()); |
| | | // 2. çææ¹æ¬¡å·ï¼ç¼ç è§åï¼åç¼ + æ¥æ + 产线ç¼ç + æµæ°´å·ï¼ |
| | | String code = generateBatchCode(line.getCode()); |
| | | |
| | | // 3. æå
¥æ¹æ¬¡ï¼äº§çº¿ç¼ç /åç§°åä½åå¡«ï¼ |
| | | // 3. æå
¥æ¹æ¬¡ï¼äº§çº¿ç¼ç /åç§°åä½åå¡«ï¼å¾éç»å®æçæ¶æ¹æ¬¡ç´æ¥è¿å
¥ç产ä¸ï¼ |
| | | boolean bindPallets = CollUtil.isNotEmpty(createReqVO.getPalletIds()); |
| | | MesProBatchDO batch = BeanUtils.toBean(createReqVO, MesProBatchDO.class) |
| | | .setCode(code) |
| | | .setLineCode(line.getCode()) |
| | | .setLineName(line.getName()) |
| | | .setBagQuantity(0) |
| | | .setPalletQuantity(0) |
| | | .setStatus(MesProBatchStatusEnum.DRAFT.getStatus()); |
| | | .setStatus(bindPallets ? MesProBatchStatusEnum.PRODUCING.getStatus() |
| | | : MesProBatchStatusEnum.DRAFT.getStatus()); |
| | | batchMapper.insert(batch); |
| | | |
| | | // 4. æå
¥ç产人åé
ç½® |
| | | insertBatchWorkers(batch.getId(), createReqVO.getWorkers()); |
| | | // 5. çææ¹æ¬¡å®æ´æ§æè¦ |
| | | // 5. ç»å®æçï¼çº§èçææ£å¼æçç å¹¶å½å
¥æçä¸è¢ç ï¼å¤±è´¥æ´ä½åæ»ï¼ |
| | | bindPalletsToBatch(batch.getId(), createReqVO.getPalletIds()); |
| | | // 6. çææ¹æ¬¡å®æ´æ§æè¦ |
| | | integrityService.recordBatchIntegrity(batch.getId()); |
| | | return batch.getId(); |
| | | } |
| | |
| | | throw exception(PRO_BATCH_ALREADY_FILLED); |
| | | } |
| | | // 2. æ ¡éªå
³èæ°æ®å¹¶çææ£å¼æ¹æ¬¡å· |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(fillReqVO.getItemId()); |
| | | MesProLineDO line = lineService.validateLineExistsAndEnable(fillReqVO.getLineId()); |
| | | validateRelations(fillReqVO); |
| | | String code = generateBatchCode(line.getCode(), item.getCode()); |
| | | // 3. è½åºä¸å¡ä¿¡æ¯ï¼ä¿çä¸´æ¶æ¹æ¬¡ç ç¨äºå岿«ç 追溯ï¼äº§çº¿ç¼ç /åç§°åä½åå¡«ï¼ |
| | | String code = generateBatchCode(line.getCode()); |
| | | // 3. è½åºä¸å¡ä¿¡æ¯ï¼ä¿çä¸´æ¶æ¹æ¬¡ç ç¨äºå岿«ç 追溯ï¼äº§çº¿ç¼ç /åç§°åä½åå¡«ï¼å¾éç»å®æçæ¶æ¹æ¬¡ç´æ¥è¿å
¥ç产ä¸ï¼ |
| | | boolean bindPallets = CollUtil.isNotEmpty(fillReqVO.getPalletIds()); |
| | | MesProBatchDO updateObj = BeanUtils.toBean(fillReqVO, MesProBatchDO.class) |
| | | .setCode(code) |
| | | .setLineCode(line.getCode()) |
| | | .setLineName(line.getName()) |
| | | .setStatus(MesProBatchStatusEnum.DRAFT.getStatus()); |
| | | .setStatus(bindPallets ? MesProBatchStatusEnum.PRODUCING.getStatus() |
| | | : MesProBatchStatusEnum.DRAFT.getStatus()); |
| | | batchMapper.updateById(updateObj); |
| | | // 4. é建ç产人åé
ç½® |
| | | batchWorkerMapper.deleteByBatchId(fillReqVO.getId()); |
| | | insertBatchWorkers(fillReqVO.getId(), fillReqVO.getWorkers()); |
| | | // 5. çææ¹æ¬¡å®æ´æ§æè¦ï¼è¡¥å½æ£å¼ä¿¡æ¯åè¦çï¼ |
| | | // 5. ç»å®æçï¼çº§èçææ£å¼æçç å¹¶å½å
¥æçä¸è¢ç ï¼å¤±è´¥æ´ä½åæ»ï¼ |
| | | bindPalletsToBatch(fillReqVO.getId(), fillReqVO.getPalletIds()); |
| | | // 6. çææ¹æ¬¡å®æ´æ§æè¦ï¼è¡¥å½æ£å¼ä¿¡æ¯åè¦çï¼ |
| | | integrityService.recordBatchIntegrity(fillReqVO.getId()); |
| | | } |
| | | |
| | |
| | | // 2. æ ¡éªå
³èæ°æ®ï¼ç产人åï¼ |
| | | validateRelations(updateReqVO); |
| | | |
| | | // 3. æªçææ£å¼æ¹æ¬¡å·æåç§/产线ååæ¶éæ°çææ¹æ¬¡å·ï¼æ¹æ¬¡å·å
å«äº§çº¿ç¼ç + åç§ç¼ç è¦ç´ ï¼ |
| | | // 3. æªçææ£å¼æ¹æ¬¡å·æäº§çº¿ååæ¶éæ°çææ¹æ¬¡å·ï¼æ¹æ¬¡å·å
å«äº§çº¿ç¼ç è¦ç´ ï¼ |
| | | boolean codeEmpty = StrUtil.isEmpty(oldBatch.getCode()); |
| | | boolean itemChanged = !Objects.equals(oldBatch.getItemId(), updateReqVO.getItemId()); |
| | | boolean lineChanged = !Objects.equals(oldBatch.getLineId(), updateReqVO.getLineId()); |
| | | String code = oldBatch.getCode(); |
| | | MesProBatchDO updateObj = BeanUtils.toBean(updateReqVO, MesProBatchDO.class); |
| | | if (codeEmpty || itemChanged || lineChanged) { |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(updateReqVO.getItemId()); |
| | | if (codeEmpty || lineChanged) { |
| | | // åæ´äº§çº¿æ¶ï¼ç®æ 产线å¿
é¡»å¯ç¨ï¼æªåæ´åä»
æ ¡éªåå¨ï¼é¿å
åç¨äº§çº¿çå岿¹æ¬¡æ æ³ç¼è¾å
¶ä»åæ®µï¼ |
| | | MesProLineDO line = (lineChanged || codeEmpty) |
| | | ? lineService.validateLineExistsAndEnable(updateReqVO.getLineId()) |
| | | : lineService.validateLineExists(updateReqVO.getLineId()); |
| | | code = generateBatchCode(line.getCode(), item.getCode()); |
| | | code = generateBatchCode(line.getCode()); |
| | | updateObj.setLineCode(line.getCode()).setLineName(line.getName()); |
| | | } |
| | | // 4. æ´æ°æ¹æ¬¡ |
| | | // 4. æ´æ°æ¹æ¬¡ï¼å¾éç»å®æçæ¶æ¹æ¬¡ç´æ¥è¿å
¥ç产ä¸ï¼åæ¶å¾éä¸åéï¼å·²ç»å®æçä¸å¯è§£ç»ï¼ |
| | | boolean bindPallets = CollUtil.isNotEmpty(updateReqVO.getPalletIds()); |
| | | updateObj.setCode(code); |
| | | if (bindPallets) { |
| | | updateObj.setStatus(MesProBatchStatusEnum.PRODUCING.getStatus()); |
| | | } |
| | | batchMapper.updateById(updateObj); |
| | | |
| | | // 5. é建ç产人åé
ç½® |
| | | batchWorkerMapper.deleteByBatchId(updateReqVO.getId()); |
| | | insertBatchWorkers(updateReqVO.getId(), updateReqVO.getWorkers()); |
| | | // 6. æè¦è¦çèå´å«åç§/产线/çäº§æ¥æ/è®¡åæ°éï¼ç¼è¾åéæ°çæé¿å
误æ¥ç¯¡æ¹ |
| | | // 6. ç»å®æ°å¢å¾éçæçï¼çº§èçææ£å¼æçç å¹¶å½å
¥æçä¸è¢ç ï¼å¤±è´¥æ´ä½åæ»ï¼ |
| | | bindPalletsToBatch(updateReqVO.getId(), updateReqVO.getPalletIds()); |
| | | // 7. æè¦è¦çèå´å«åç§/产线/çäº§æ¥æ/è®¡åæ°éï¼ç¼è¾åéæ°çæé¿å
误æ¥ç¯¡æ¹ |
| | | integrityService.recordBatchIntegrity(updateReqVO.getId()); |
| | | } |
| | | |
| | |
| | | /** |
| | | * æ ¡éªå
³èæ°æ®ï¼ç产人åï¼è´£ä»»äºº + ç产人åé
ç½®ï¼ |
| | | * <p> |
| | | * åç§ãäº§çº¿çæ ¡éªå¨å建/æ´æ°æµç¨ä¸å
èæ§è¡ï¼éåç¼ç å䏿¹æ¬¡å·çæï¼ |
| | | * äº§çº¿çæ ¡éªå¨å建/æ´æ°æµç¨ä¸å
èæ§è¡ï¼éåç¼ç å䏿¹æ¬¡å·çæï¼ |
| | | */ |
| | | private void validateRelations(MesProBatchSaveReqVO reqVO) { |
| | | Set<Long> userIds = new HashSet<>(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¹æ¬¡ç»å®æçï¼å¯éï¼ï¼åäºå¡å
å¤ç¨æçç»å®æ¹æ¬¡é»è¾ï¼ |
| | | * çææ£å¼æçç 并级èå½å
¥æç䏿ªç»æ¹æ¬¡çè¢ç ï¼å¤±è´¥æ´ä½åæ» |
| | | */ |
| | | private void bindPalletsToBatch(Long batchId, List<Long> palletIds) { |
| | | if (CollUtil.isEmpty(palletIds)) { |
| | | return; |
| | | } |
| | | MesProPalletBindBatchReqVO bindReqVO = new MesProPalletBindBatchReqVO(); |
| | | bindReqVO.setBatchId(batchId); |
| | | bindReqVO.setIds(palletIds); |
| | | palletService.bindBatch(bindReqVO); |
| | | } |
| | | |
| | | /** |
| | | * çææ¹æ¬¡å· |
| | | * <p> |
| | | * ç¼ç è§åï¼åºå®åç¼(PC) + æ¥æ(yyyyMMdd) + è¾å
¥å符(产线ç¼ç + åç§ç¼ç ) + æµæ°´å·(ææ¥å¾ªç¯) |
| | | * ç¼ç è§åï¼åºå®åç¼(PC) + æ¥æ(yyyyMMdd) + è¾å
¥å符(产线ç¼ç ) + æµæ°´å·(ææ¥å¾ªç¯) |
| | | * |
| | | * @param lineCode 产线ç¼ç |
| | | * @param itemCode åç§ï¼ç©æï¼ç¼ç |
| | | * @return æ¹æ¬¡å· |
| | | */ |
| | | private String generateBatchCode(String lineCode, String itemCode) { |
| | | String inputChar = StrUtil.emptyToDefault(lineCode, "") + StrUtil.emptyToDefault(itemCode, ""); |
| | | private String generateBatchCode(String lineCode) { |
| | | String inputChar = StrUtil.emptyToDefault(lineCode, ""); |
| | | return autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PRO_BATCH_CODE.getCode(), inputChar); |
| | | } |
| | | |
| | |
| | | List<MesProPalletDO> getPalletListByBatchId(Long batchId); |
| | | |
| | | /** |
| | | * è·å¾æªç»å®çäº§æ¹æ¬¡çä¸´æ¶æçå表ï¼ä¾æ¹æ¬¡æ°å¢/è¡¥å½ç»å®æçä¸æä½¿ç¨ï¼ |
| | | * |
| | | * @return æçç å表 |
| | | */ |
| | | List<MesProPalletDO> getUnboundPalletList(); |
| | | |
| | | /** |
| | | * è·å¾æçç åè¡¨ï¼æç¼å·åè¡¨ï¼ |
| | | * |
| | | * @param ids ç¼å·å表 |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletBindBatchReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletPreGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.batch.MesProBatchMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.pallet.MesProPalletMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProBagCodeStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProBatchStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProPalletStatusEnum; |
| | | import jakarta.annotation.Resource; |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setPalletNo(palletNo) |
| | | .setCapacity(createReqVO.getCapacity()) |
| | | .setBagCount(0) |
| | | .setAutoGenerated(false) |
| | | .setStatus(MesProPalletStatusEnum.IN_USE.getStatus()) |
| | |
| | | for (int i = 0; i < reqVO.getCount(); i++) { |
| | | list.add(new MesProPalletDO() |
| | | .setTempCode("PL-" + StrUtil.padPre(String.valueOf(startSeq + i), 8, '0')) |
| | | .setCapacity(reqVO.getCapacity()) |
| | | .setBagCount(0) |
| | | .setAutoGenerated(false) |
| | | .setStatus(MesProPalletStatusEnum.IN_USE.getStatus()) |
| | |
| | | } |
| | | pallets.add(pallet); |
| | | } |
| | | // 3. åé
æ£å¼æçç ï¼æ¹æ¬¡å· + -P + 2 使çåºå·ï¼å«é»è¾å é¤è®°å½åä¸åºå·ï¼ä¿è¯ä¸åéãç å¼å¯ä¸ï¼ |
| | | // 3. 级èåå¤ï¼æç䏿ªç»æ¹æ¬¡çè¢ç éæçä¸èµ·å½å
¥æ¹æ¬¡ï¼åç§é¡»ä¸æ¹æ¬¡å·²æè¢ç ä¸è´ |
| | | List<MesProBagCodeDO> bags = bagCodeMapper.selectUnboundListByPalletIds(ids); |
| | | List<Long> bindBagIds = new ArrayList<>(); |
| | | Set<Long> bagItemIds = new LinkedHashSet<>(); |
| | | for (MesProBagCodeDO bag : bags) { |
| | | if (!MesProBagCodeStatusEnum.GENERATED.getStatus().equals(bag.getStatus()) |
| | | && !MesProBagCodeStatusEnum.PRINTED.getStatus().equals(bag.getStatus())) { |
| | | continue; |
| | | } |
| | | bindBagIds.add(bag.getId()); |
| | | if (bag.getItemId() != null) { |
| | | bagItemIds.add(bag.getItemId()); |
| | | } |
| | | } |
| | | if (!bindBagIds.isEmpty()) { |
| | | bagItemIds.addAll(bagCodeMapper.selectDistinctItemIdsByBatchId(batch.getId())); |
| | | if (bagItemIds.size() > 1) { |
| | | throw exception(PRO_BAG_CODE_BIND_BATCH_ITEM_MISMATCH); |
| | | } |
| | | } |
| | | // 4. åé
æ£å¼æçç ï¼æ¹æ¬¡å· + -P + 2 使çåºå·ï¼å«é»è¾å é¤è®°å½åä¸åºå·ï¼ä¿è¯ä¸åéãç å¼å¯ä¸ï¼ |
| | | int startNo = palletMapper.selectMaxPalletNo(batch.getId()) + 1; |
| | | for (int i = 0; i < pallets.size(); i++) { |
| | | int palletNo = startNo + i; |
| | |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setPalletNo(palletNo)); |
| | | // æçä¸è¢ç çå使çç ç±ä¸´æ¶ç æ´æ°ä¸ºæ£å¼ç |
| | | bagCodeMapper.updatePalletCodeByPalletId(pallets.get(i).getId(), |
| | | batch.getCode() + "-P" + StrUtil.padPre(String.valueOf(palletNo), 2, '0')); |
| | | } |
| | | // 4. ååæ¹æ¬¡æçç æ°é |
| | | // 5. æçä¸è¢ç æ¹éç»å®æ¬æ¹æ¬¡ |
| | | if (!bindBagIds.isEmpty() && bagCodeMapper.bindBatchByIds(bindBagIds, batch.getId(), batch.getCode(), |
| | | List.of(MesProBagCodeStatusEnum.GENERATED.getStatus(), |
| | | MesProBagCodeStatusEnum.PRINTED.getStatus())) != bindBagIds.size()) { |
| | | throw exception(PRO_BAG_CODE_STATUS_NOT_GENERATED); |
| | | } |
| | | // 6. ååæ¹æ¬¡æçç æ°é䏿æè¢ç æ°é |
| | | batchMapper.updateById(new MesProBatchDO().setId(batch.getId()) |
| | | .setPalletQuantity((batch.getPalletQuantity() == null ? 0 : batch.getPalletQuantity()) + pallets.size())); |
| | | .setPalletQuantity((batch.getPalletQuantity() == null ? 0 : batch.getPalletQuantity()) + pallets.size()) |
| | | .setBagQuantity(bagCodeMapper.selectEffectiveCountByBatchId(batch.getId()))); |
| | | return pallets.size(); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<MesProPalletDO> getUnboundPalletList() { |
| | | return palletMapper.selectUnboundList(); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesProPalletDO> getPalletListByIds(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return List.of(); |
| | |
| | | throw exception(MES_TRACE_CODE_NOT_FOUND); |
| | | } |
| | | // 2. èåå
¨ç¨ä¿¡æ¯ |
| | | MesProTracePublicRespVO result = buildRespVO(rawCode, traceCode, entry.sourceType, entry.batchId); |
| | | MesProTracePublicRespVO result = buildRespVO(rawCode, traceCode, entry.sourceType, entry.batchId, entry.bagItemId); |
| | | recordConsumerScan(rawCode, traceCode, entry.sourceType, entry.batchId, true); |
| | | return result; |
| | | } catch (RuntimeException ex) { |
| | |
| | | // â è¢ç |
| | | MesProBagCodeDO bag = bagCodeService.getBagCodeByCode(traceCode); |
| | | if (bag != null) { |
| | | return new TraceEntry("BAG", bag.getBatchId()); |
| | | return new TraceEntry("BAG", bag.getBatchId(), bag.getItemId()); |
| | | } |
| | | // â¡ æçç |
| | | MesProPalletDO pallet = palletService.getPalletByCode(traceCode); |
| | | if (pallet != null) { |
| | | return new TraceEntry("PALLET", pallet.getBatchId()); |
| | | return new TraceEntry("PALLET", pallet.getBatchId(), null); |
| | | } |
| | | // â¢ æ¹æ¬¡ç ï¼å«ä¸´æ¶æ¹æ¬¡ç ï¼getBatchByCode å
é¨å
¼å®¹ï¼ |
| | | MesProBatchDO batch = batchService.getBatchByCode(traceCode); |
| | | if (batch != null) { |
| | | return new TraceEntry("BATCH", batch.getId()); |
| | | return new TraceEntry("BATCH", batch.getId(), null); |
| | | } |
| | | return new TraceEntry("", null); |
| | | return new TraceEntry("", null, null); |
| | | } |
| | | |
| | | // ==================== èåæå»º ==================== |
| | | |
| | | private MesProTracePublicRespVO buildRespVO(String requestCode, String traceCode, String sourceType, Long batchId) { |
| | | private MesProTracePublicRespVO buildRespVO(String requestCode, String traceCode, String sourceType, Long batchId, Long bagItemId) { |
| | | MesProBatchDO batch = batchService.getBatch(batchId); |
| | | if (batch == null) { |
| | | throw exception(MES_TRACE_CODE_NOT_FOUND); |
| | |
| | | resp.setSourceType(sourceType); |
| | | resp.setRequestCode(requestCode); |
| | | // åç§åºå |
| | | fillItem(resp, batch); |
| | | fillItem(resp, batch, bagItemId); |
| | | // æ¹æ¬¡åºå |
| | | resp.setBatchCode(batch.getCode()).setTempCode(batch.getTempCode()) |
| | | .setBatchStatus(batch.getStatus()).setBatchStatusName(batchStatusName(batch.getStatus())) |
| | |
| | | return resp; |
| | | } |
| | | |
| | | private void fillItem(MesProTracePublicRespVO resp, MesProBatchDO batch) { |
| | | if (batch.getItemId() == null) { |
| | | /** |
| | | * åç§å·²ä¸æ²å°è¢ç æ°æ®å
ï¼ä¼å
åæ«ç è¢ç åç§ï¼å岿¹æ¬¡åéæ¹æ¬¡åç§ï¼æ¹æ¬¡/æçå
¥å£åæ¹å
ä»»ä¸è¢ç åç§ |
| | | */ |
| | | private void fillItem(MesProTracePublicRespVO resp, MesProBatchDO batch, Long bagItemId) { |
| | | Long itemId = bagItemId != null ? bagItemId : batch.getItemId(); |
| | | if (itemId == null) { |
| | | List<MesProBagCodeDO> bags = bagCodeService.getBagCodeListByBatchId(batch.getId()); |
| | | itemId = bags == null ? null : bags.stream().map(MesProBagCodeDO::getItemId) |
| | | .filter(id -> id != null).findFirst().orElse(null); |
| | | } |
| | | if (itemId == null) { |
| | | return; |
| | | } |
| | | MesMdmItemDO item = mdmItemService.getItem(batch.getItemId()); |
| | | MesMdmItemDO item = mdmItemService.getItem(itemId); |
| | | if (item == null) { |
| | | return; |
| | | } |
| | |
| | | }; |
| | | } |
| | | |
| | | private record TraceEntry(String sourceType, Long batchId) { |
| | | private record TraceEntry(String sourceType, Long batchId, Long bagItemId) { |
| | | } |
| | | |
| | | } |
| | |
| | | var CODE_INPUT = document.getElementById('codeInput'); |
| | | var SEARCH_BTN = document.getElementById('searchBtn'); |
| | | |
| | | var BATCH_STATUS = { 10: ['è稿', 'gray'], 20: ['ç产ä¸', 'blue'], 30: ['已宿', 'green'], 40: ['å·²ä½åº', 'red'] }; |
| | | var BAG_STATUS = { 10: ['å·²çæ', 'gray'], 20: ['已导åºå°å·', 'blue'], 30: ['å·²ä½åº', 'red'] }; |
| | | var QUALITY_RESULT = { 0: ['å¤çä¸', 'gray'], 1: ['åæ ¼', 'green'], 2: ['ä¸åæ ¼', 'red'] }; |
| | | var WORKER_TYPE = { 10: 'ç»é¿', 20: 'æä½å·¥', 30: 'å
è£
å·¥', 40: 'è´¨æ£å', 50: 'å
¶ä»' }; |
| | | var FLOW_DIRECTION = { 1: ['å
¥åº', 'green'], 2: ['åºåº', 'blue'] }; |
| | | var FLOW_BIZ_TYPE = { |
| | | 110: 'éè´å
¥åº', 111: 'éè´å
¥åºåæ¶', 112: 'è°æ¨åºåº', 113: 'è°æ¨å
¥åº', |
| | |
| | | var html = ''; |
| | | html += buildVerifyCard(d); |
| | | html += buildItemCard(d); |
| | | html += buildBatchCard(d); |
| | | html += buildQualityCard(d); |
| | | html += buildWorkerCard(d); |
| | | html += buildInboundCard(d); |
| | | html += buildPalletCard(d); |
| | | html += buildBagCard(d); |
| | | html += buildOptionalCard(d); |
| | | STATE.innerHTML = html || '<div class="empty-tip">ææ è¿½æº¯æ°æ®</div>'; |
| | | window.scrollTo({ top: 0, behavior: 'smooth' }); |
| | |
| | | ); |
| | | } |
| | | |
| | | // åºå2ï¼çäº§æ¹æ¬¡ |
| | | function buildBatchCard(d) { |
| | | if (!d.batchCode && !d.tempCode) return ''; |
| | | var status = statusBadge(BATCH_STATUS, d.batchStatus); |
| | | return card('çäº§æ¹æ¬¡', status, |
| | | kv('æ¹æ¬¡å·', text(d.batchCode)) + |
| | | kv('ç¶æ', status) + |
| | | kv('çäº§æ¥æ', fmtDate(d.produceDate)) + |
| | | kv('产线', text(d.lineName ? (d.lineName + (d.lineCode ? ' / ' + d.lineCode : '')) : d.lineCode)) + |
| | | kv('责任人', text(d.ownerUserName)) + |
| | | kv('è®¡åæ°é', fmtNum(d.planQuantity) === '-' ? '-' : fmtNum(d.planQuantity)) + |
| | | kv('å·²çæè¢ç ', fmtNum(d.bagQuantity)) + |
| | | kv('å·²çææç', fmtNum(d.palletQuantity)) + |
| | | kv('å
¥åºæ¶é´', fmtDate(d.inboundTime)) + |
| | | (d.remark ? kv('夿³¨', text(d.remark)) : ''), |
| | | { collapsible: true, open: true } |
| | | ); |
| | | } |
| | | |
| | | // åºå3ï¼ç§åè´¨æ£ |
| | | function buildQualityCard(d) { |
| | | var q = d.quality; |
| | | if (!q) return ''; |
| | | var result = QUALITY_RESULT[q.result]; |
| | | var badge = result |
| | | ? '<span class="badge-big ' + result[1] + '">' + esc(result[0]) + '</span>' |
| | | : '<span class="badge-big gray">æªç¥</span>'; |
| | | |
| | | var rows = ''; |
| | | if (q.indicators && q.indicators.length) { |
| | | rows = '<table class="mini-table"><thead><tr><th>ææ </th><th>æ£æµå¼</th><th>æ åèå´</th><th>ç»æ</th></tr></thead><tbody>'; |
| | | q.indicators.forEach(function (i) { |
| | | var range = (i.minValue !== null && i.minValue !== undefined && i.maxValue !== null && i.maxValue !== undefined) |
| | | ? esc(i.minValue) + ' ~ ' + esc(i.maxValue) : '-'; |
| | | var pass = (i.pass === true) |
| | | ? '<span class="badge green">åæ ¼</span>' |
| | | : (i.pass === false ? '<span class="badge red">ä¸åæ ¼</span>' : '<span class="badge gray">--</span>'); |
| | | rows += '<tr><td>' + text(i.indicatorName) + '</td><td>' + text(i.value) + '</td><td>' + range + '</td><td>' + pass + '</td></tr>'; |
| | | }); |
| | | rows += '</tbody></table>'; |
| | | } |
| | | |
| | | return card('ç§åè´¨æ£', badge, |
| | | kv('æ£éªç»è®º', badge) + |
| | | kv('æ£éªå', text(q.inspectorName)) + |
| | | kv('æ£éªæ¶é´', fmtDate(q.inspectedAt)) + |
| | | (q.reason ? kv('ä¸åæ ¼åå ', text(q.reason)) : '') + |
| | | (rows ? '<div style="margin-top:8px">' + rows + '</div>' : ''), |
| | | { collapsible: true, open: false } |
| | | ); |
| | | } |
| | | |
| | | // åºå4ï¼ç产人å |
| | | function buildWorkerCard(d) { |
| | | if (isEmptyList(d.workers)) return ''; |
| | | var html = '<div class="pill-list">'; |
| | | d.workers.forEach(function (w) { |
| | | var name = w.userName || '-'; |
| | | var type = w.workerTypeName || (WORKER_TYPE[w.workerType] || ''); |
| | | var color = { 10: 'var(--blue)', 20: 'var(--green)', 30: 'var(--primary-light)', 40: 'var(--red)', 50: 'var(--gray)' }[w.workerType] || 'var(--gray)'; |
| | | html += '<span class="pill"><span class="dot" style="background:' + color + '"></span>' + |
| | | esc(type) + 'ï¼' + esc(name) + '</span>'; |
| | | }); |
| | | html += '</div>'; |
| | | return card('ç产人å', null, html, { collapsible: true, open: false }); |
| | | } |
| | | |
| | | // åºå5ï¼æ«ç å
¥åºäºä»¶ |
| | | function buildInboundCard(d) { |
| | | var e = d.inbound; |
| | | if (!e) return ''; |
| | | return card('æ«ç å
¥åº', null, |
| | | kv('äºä»¶å·', text(e.eventId)) + |
| | | kv('å
¥åºæ°é', fmtNum(e.quantity)) + |
| | | kv('设å¤ç¼ç ', text(e.deviceCode)) + |
| | | kv('产线', text(e.lineCode)) + |
| | | kv('å
¥åºæ¶é´', fmtDate(e.eventTime)), |
| | | { collapsible: true, open: false } |
| | | ); |
| | | } |
| | | |
| | | // åºå6ï¼æç |
| | | function buildPalletCard(d) { |
| | | if (isEmptyList(d.pallets)) return ''; |
| | | var countHtml = 'å
± ' + esc(d.palletCount || d.pallets.length) + ' 个'; |
| | | var rows = '<table class="mini-table"><thead><tr><th>æçç </th><th>åºå·</th><th>å·²è£
/å¯è£
</th></tr></thead><tbody>'; |
| | | d.pallets.forEach(function (p) { |
| | | rows += '<tr><td>' + text(p.code) + '</td><td>' + fmtNum(p.palletNo) + '</td><td>' + |
| | | fmtNum(p.bagCount) + ' / ' + fmtNum(p.capacity) + '</td></tr>'; |
| | | }); |
| | | rows += '</tbody></table>'; |
| | | return card('æçä¿¡æ¯', countHtml, rows, { collapsible: true, open: false }); |
| | | } |
| | | |
| | | // åºå7ï¼è¢ç ï¼ä¸è¢ä¸ç ï¼ |
| | | function buildBagCard(d) { |
| | | if (d.bagTotal === null || d.bagTotal === undefined || d.bagTotal === 0) return ''; |
| | | var countHtml = 'å
± ' + esc(d.bagTotal) + ' 个' + (d.bags && d.bags.length < d.bagTotal ? 'ï¼å±ç¤ºå ' + esc(d.bags.length) + ' 个ï¼' : ''); |
| | | var rows = '<table class="mini-table"><thead><tr><th>è¢ç </th><th>è¢å·</th><th>æç</th><th>ç¶æ</th></tr></thead><tbody>'; |
| | | (d.bags || []).forEach(function (b) { |
| | | rows += '<tr><td>' + text(b.code) + '</td><td>' + fmtNum(b.bagNo) + '</td><td>' + text(b.palletCode) + '</td><td>' + |
| | | statusBadge(BAG_STATUS, b.status) + '</td></tr>'; |
| | | }); |
| | | rows += '</tbody></table>'; |
| | | return card('è¢ç ä¿¡æ¯', countHtml, |
| | | '<div class="scroll-list">' + rows + '</div>', |
| | | { collapsible: true, open: false } |
| | | ); |
| | | } |
| | | |
| | | // åºå8ï¼å¯éæ©å±ï¼éè´æ¥æº / ç§åæµåä¿¡æ¯ï¼éå®åºåºï¼ / å å·¥æµè½¬ï¼ï¼ææ°æ®æå±ç¤º |
| | | // åºå2ï¼å¯éæ©å±ï¼éè´æ¥æº / ç§åæµåä¿¡æ¯ï¼ä»
éå®åºåºï¼ / å å·¥æµè½¬ï¼ï¼ææ°æ®æå±ç¤º |
| | | function buildOptionalCard(d) { |
| | | var html = ''; |
| | | if (!isEmptyList(d.purchaseSources)) { |
| | |
| | | rows += '</tbody></table>'; |
| | | html += card('éè´æ¥æº', null, rows, { collapsible: true, open: false }); |
| | | } |
| | | if (!isEmptyList(d.seedFlows)) { |
| | | // åªå±ç¤ºéå®åºåºï¼bizType=119ï¼çæµæ°´ï¼ç产å
¥åº/产å产åºçä¸å±ç¤º |
| | | var salesFlows = (d.seedFlows || []).filter(function (f) { return f.bizType === 119; }); |
| | | if (!isEmptyList(salesFlows)) { |
| | | var rows2 = '<table class="mini-table"><thead><tr><th>æ¹å</th><th>ä¸å¡</th><th>æ¥æºåå·</th><th>客æ·</th><th>æ°é</th><th>æ¶é´</th><th>ä»åº/åºåº</th></tr></thead><tbody>'; |
| | | d.seedFlows.forEach(function (f) { |
| | | salesFlows.forEach(function (f) { |
| | | var qty = (f.quantity === null || f.quantity === undefined) ? '-' : fmtNum(Math.abs(Number(f.quantity))); |
| | | var wh = [f.warehouseName, f.locationName].filter(Boolean).join(' / ') || '-'; |
| | | rows2 += '<tr><td>' + statusBadge(FLOW_DIRECTION, f.type) + '</td><td>' + text(FLOW_BIZ_TYPE[f.bizType] || f.bizType) + |