feat(mes): 新增袋码破损替换功能
- 添加袋码替换相关的错误码定义
- 在数据库表mes_pro_bag_code中增加作废时间和作废原因字段
- 创建袋码替换记录表mes_pro_bag_code_replace用于追踪替换关系
- 添加袋码破损替换菜单权限和接口
- 实现replaceBagCodes方法处理袋码替换逻辑
- 更新袋码追溯信息展示替换关系
- 支持已绑定托盘的袋码替换时继承托盘关系
- 添加替换相关的数据访问对象和映射器方法
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f3e7]: |
| | | - complementary [ref=f3e9]: |
| | | - generic [ref=f3e10]: |
| | | - generic [ref=f3e11] [cursor=pointer] |
| | | - link "å·¥ä¸AIæºé å¹³å° å·¥ä¸AIæºé å¹³å°" [ref=f3e16] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "å·¥ä¸AIæºé å¹³å°" [ref=f3e19] |
| | | - generic [ref=f3e20]: å·¥ä¸AIæºé å¹³å° |
| | | - menu [ref=f3e23]: |
| | | - menuitem "é¦é¡µ" [ref=f3e24] [cursor=pointer] |
| | | - listitem [ref=f3e29]: |
| | | - generic [ref=f3e30] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f3e38]: |
| | | - generic [ref=f3e39] [cursor=pointer]: ä¸è¢ä¸ç 管ç |
| | | - list [ref=f3e349]: |
| | | - menuitem "æ¹æ¬¡ç产管ç" [ref=f3e350] [cursor=pointer] |
| | | - menuitem "èµç 管ç" [ref=f3e355] [cursor=pointer] |
| | | - menuitem "æçç 管ç" [ref=f3e361] [cursor=pointer] |
| | | - menuitem "产线维æ¤" [ref=f3e368] [cursor=pointer] |
| | | - listitem [ref=f3e45]: |
| | | - generic [ref=f3e46] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - generic [ref=f3e53] [cursor=pointer] |
| | | - generic [ref=f3e58]: |
| | | - generic [ref=f3e59]: |
| | | - banner [ref=f3e60]: |
| | | - button [ref=f3e61] [cursor=pointer] |
| | | - button [ref=f3e64] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f3e69]: |
| | | - list [ref=f3e70]: |
| | | - listitem [ref=f3e71]: |
| | | - link "é¦é¡µ" [disabled] [ref=f3e72] |
| | | - generic [ref=f3e77]: |
| | | - generic [ref=f3e79] [cursor=pointer]: |
| | | - generic [ref=f3e83]: æç´¢ |
| | | - generic [ref=f3e84]: Ctrl K |
| | | - button [ref=f3e86] [cursor=pointer] |
| | | - button "dark" [ref=f3e91] [cursor=pointer] |
| | | - button [ref=f3e100] [cursor=pointer] |
| | | - button [ref=f3e106] [cursor=pointer] |
| | | - button [ref=f3e109] [cursor=pointer] |
| | | - button [ref=f3e115] [cursor=pointer]: |
| | | - button [ref=f3e117] |
| | | - button "å·¥ä½å°" [ref=f3e121] [cursor=pointer] |
| | | - button [ref=f3e125] [cursor=pointer]: |
| | | - img "è¶
级管çå" [ref=f3e130] |
| | | - generic [ref=f3e132]: |
| | | - generic [ref=f3e133]: é¦é¡µ |
| | | - generic [ref=f3e152]: |
| | | - button [ref=f3e153] [cursor=pointer] |
| | | - generic [ref=f3e160] [cursor=pointer] |
| | | - generic [ref=f3e164] [cursor=pointer] |
| | | - main [ref=f3e171]: |
| | | - generic [ref=f3e174]: |
| | | - generic [ref=f3e175]: |
| | | - generic [ref=f3e185] [cursor=pointer]: |
| | | - generic [ref=f3e186]: åç§æ»æ° |
| | | - generic [ref=f3e187]: "1" |
| | | - generic [ref=f3e198] [cursor=pointer]: |
| | | - generic [ref=f3e199]: MES åç§ |
| | | - generic [ref=f3e200]: "0" |
| | | - generic [ref=f3e211] [cursor=pointer]: |
| | | - generic [ref=f3e212]: åç§åç±» |
| | | - generic [ref=f3e213]: "1" |
| | | - generic [ref=f3e222] [cursor=pointer]: |
| | | - generic [ref=f3e223]: 计éåä½ |
| | | - generic [ref=f3e224]: "1" |
| | | - generic [ref=f3e226]: |
| | | - generic [ref=f3e234] [cursor=pointer]: |
| | | - generic [ref=f3e235]: 产线 |
| | | - generic [ref=f3e236]: "1" |
| | | - generic [ref=f3e248] [cursor=pointer]: |
| | | - generic [ref=f3e249]: çäº§æ¹æ¬¡ |
| | | - generic [ref=f3e250]: "1" |
| | | - generic [ref=f3e259] [cursor=pointer]: |
| | | - generic [ref=f3e260]: è¢ç |
| | | - generic [ref=f3e261]: "100" |
| | | - generic [ref=f3e272] [cursor=pointer]: |
| | | - generic [ref=f3e273]: æçç |
| | | - generic [ref=f3e274]: "10" |
| | | - generic [ref=f3e276]: |
| | | - generic [ref=f3e280]: |
| | | - generic [ref=f3e281]: è¢ç çæè¶å¿ |
| | | - generic [ref=f3e283]: |
| | | - generic [ref=f3e284] [cursor=pointer]: |
| | | - generic [ref=f3e285]: |
| | | - radio "è¿ 7 天" [checked] |
| | | - generic [ref=f3e286]: è¿ 7 天 |
| | | - generic [ref=f3e287] [cursor=pointer]: |
| | | - generic [ref=f3e288]: |
| | | - radio "è¿ 30 天" |
| | | - generic [ref=f3e289]: è¿ 30 天 |
| | | - generic [ref=f3e294]: æ¹æ¬¡ç¶æåå¸ |
| | | - generic [ref=f3e303]: è¢ç ç¶æåå¸ |
| | | - generic [ref=f3e312]: |
| | | - generic [ref=f3e313]: å¿«æ·å
¥å£ |
| | | - generic [ref=f3e317]: |
| | | - generic [ref=f3e318]: åç§ç®¡ç |
| | | - generic [ref=f3e326]: åç§åç±» |
| | | - generic [ref=f3e334]: æ¹æ¬¡ç产 |
| | | - generic [ref=f3e343]: èµç 管ç |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f3e7]: |
| | | - complementary [ref=f3e9]: |
| | | - generic [ref=f3e10]: |
| | | - generic [ref=f3e11] [cursor=pointer] |
| | | - link "å·¥ä¸AIæºé å¹³å° å·¥ä¸AIæºé å¹³å°" [ref=f3e16] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "å·¥ä¸AIæºé å¹³å°" [ref=f3e19] |
| | | - generic [ref=f3e20]: å·¥ä¸AIæºé å¹³å° |
| | | - menu [ref=f3e23]: |
| | | - menuitem "é¦é¡µ" [ref=f3e24] [cursor=pointer] |
| | | - listitem [ref=f3e29]: |
| | | - generic [ref=f3e30] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f3e38]: |
| | | - generic [ref=f3e39] [cursor=pointer]: ä¸è¢ä¸ç 管ç |
| | | - list [ref=f3e349]: |
| | | - menuitem "æ¹æ¬¡ç产管ç" [ref=f3e350] [cursor=pointer] |
| | | - menuitem "èµç 管ç" [active] [ref=f3e355] [cursor=pointer] |
| | | - menuitem "æçç 管ç" [ref=f3e361] [cursor=pointer] |
| | | - menuitem "产线维æ¤" [ref=f3e368] [cursor=pointer] |
| | | - listitem [ref=f3e45]: |
| | | - generic [ref=f3e46] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - generic [ref=f3e53] [cursor=pointer] |
| | | - generic [ref=f3e58]: |
| | | - generic [ref=f3e59]: |
| | | - banner [ref=f3e60]: |
| | | - button [ref=f3e61] [cursor=pointer] |
| | | - button [ref=f3e64] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f3e69]: |
| | | - list [ref=f3e70]: |
| | | - listitem [ref=f3e375]: |
| | | - link "ä¸è¢ä¸ç 管ç" [ref=f3e376] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f3e380] |
| | | - listitem [ref=f3e383]: |
| | | - link "èµç 管ç" [disabled] [ref=f3e384] |
| | | - generic [ref=f3e77]: |
| | | - generic [ref=f3e79] [cursor=pointer]: |
| | | - generic [ref=f3e83]: æç´¢ |
| | | - generic [ref=f3e84]: Ctrl K |
| | | - button [ref=f3e86] [cursor=pointer] |
| | | - button "dark" [ref=f3e91] [cursor=pointer] |
| | | - button [ref=f3e100] [cursor=pointer] |
| | | - button [ref=f3e106] [cursor=pointer] |
| | | - button [ref=f3e109] [cursor=pointer] |
| | | - button [ref=f3e115] [cursor=pointer]: |
| | | - button [ref=f3e117] |
| | | - button "å·¥ä½å°" [ref=f3e121] [cursor=pointer] |
| | | - button [ref=f3e125] [cursor=pointer]: |
| | | - img "è¶
级管çå" [ref=f3e130] |
| | | - generic [ref=f3e132]: |
| | | - generic [ref=f3e137]: |
| | | - generic [ref=f3e138] [cursor=pointer]: é¦é¡µ |
| | | - generic [ref=f3e392] [cursor=pointer]: èµç 管ç |
| | | - generic [ref=f3e152]: |
| | | - button [ref=f3e153] [cursor=pointer] |
| | | - generic [ref=f3e160] [cursor=pointer] |
| | | - generic [ref=f3e164] [cursor=pointer] |
| | | - main [ref=f3e171]: |
| | | - generic [ref=f3e174]: |
| | | - generic [ref=f3e175]: |
| | | - generic [ref=f3e185] [cursor=pointer]: |
| | | - generic [ref=f3e186]: åç§æ»æ° |
| | | - generic [ref=f3e187]: "1" |
| | | - generic [ref=f3e198] [cursor=pointer]: |
| | | - generic [ref=f3e199]: MES åç§ |
| | | - generic [ref=f3e200]: "0" |
| | | - generic [ref=f3e211] [cursor=pointer]: |
| | | - generic [ref=f3e212]: åç§åç±» |
| | | - generic [ref=f3e213]: "1" |
| | | - generic [ref=f3e222] [cursor=pointer]: |
| | | - generic [ref=f3e223]: 计éåä½ |
| | | - generic [ref=f3e224]: "1" |
| | | - generic [ref=f3e226]: |
| | | - generic [ref=f3e234] [cursor=pointer]: |
| | | - generic [ref=f3e235]: 产线 |
| | | - generic [ref=f3e236]: "1" |
| | | - generic [ref=f3e248] [cursor=pointer]: |
| | | - generic [ref=f3e249]: çäº§æ¹æ¬¡ |
| | | - generic [ref=f3e250]: "1" |
| | | - generic [ref=f3e259] [cursor=pointer]: |
| | | - generic [ref=f3e260]: è¢ç |
| | | - generic [ref=f3e261]: "100" |
| | | - generic [ref=f3e272] [cursor=pointer]: |
| | | - generic [ref=f3e273]: æçç |
| | | - generic [ref=f3e274]: "10" |
| | | - generic [ref=f3e276]: |
| | | - generic [ref=f3e280]: |
| | | - generic [ref=f3e281]: è¢ç çæè¶å¿ |
| | | - generic [ref=f3e283]: |
| | | - generic [ref=f3e284] [cursor=pointer]: |
| | | - generic [ref=f3e285]: |
| | | - radio "è¿ 7 天" [checked] |
| | | - generic [ref=f3e286]: è¿ 7 天 |
| | | - generic [ref=f3e287] [cursor=pointer]: |
| | | - generic [ref=f3e288]: |
| | | - radio "è¿ 30 天" |
| | | - generic [ref=f3e289]: è¿ 30 天 |
| | | - generic [ref=f3e294]: æ¹æ¬¡ç¶æåå¸ |
| | | - generic [ref=f3e303]: è¢ç ç¶æåå¸ |
| | | - generic [ref=f3e312]: |
| | | - generic [ref=f3e313]: å¿«æ·å
¥å£ |
| | | - generic [ref=f3e317]: |
| | | - generic [ref=f3e318]: åç§ç®¡ç |
| | | - generic [ref=f3e326]: åç§åç±» |
| | | - generic [ref=f3e334]: æ¹æ¬¡ç产 |
| | | - generic [ref=f3e343]: èµç 管ç |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ä¸è¢ä¸ç ç ´æè¢ç æ¿æ¢ - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - èµç 管çï¼è¢ç å表ãè¢ç 详æ
ãæ«ç 追溯 |
| | | - æ¹æ¬¡ç产管çï¼æ¹æ¬¡è¯¦æ
åææè¢ç æ°éå±ç¤º |
| | | - æçç 管çï¼æç详æ
åç»å®è¢ç å表 |
| | | |
| | | æ¬æ¬¡åªæ°å¢å端æ¥å£ååæ®µçº¦å®ï¼ä¸ä¿®æ¹å端项ç®ä»£ç ã |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. ç产人åå¨è¢ç å表ä¸éæ©å䏿¹æ¬¡ä¸å
è£
ç ´æçè¢ç ï¼è®°å½å
¶æ°æ®åºç¼å·ã |
| | | 2. å端è°ç¨ç ´ææ¿æ¢æ¥å£ï¼ä¼ å
¥æ¹æ¬¡ç¼å·ãæ§è¢ç ç¼å·å表åç ´æåå ã |
| | | 3. å端å¨ä¸ä¸ªäºå¡å
å°æ§è¢ç æ¹ä¸ºâå·²ä½åºâï¼çæçéæ°è¢ç ï¼å¹¶è¿åæ§ç 䏿°ç ä¸å¯¹ä¸æ å°ã |
| | | 4. 妿æ§è¢ç å·²ç»å®å¯ç¨æçï¼æ°è¢ç èªå¨ç»§æ¿åæçï¼æ§ç 仿çå½åææè¢ç ä¸ç§»é¤ï¼æçå·²ç»å®æ°éä¿æä¸åã |
| | | 5. åç«¯æ ¹æ®ååºä¸ç `replaceUuid` ææ°è¢ç åè¡¨å·æ°è¢ç å表ï¼å¹¶è°ç¨ç°æè¢ç å¯¼åºæ¥å£å®ææ°æ ç¾æå°ã |
| | | 6. æ°è¢ç 导åºåç¶æç±âå·²çæâå为â已导åºå°å·âï¼æ§è¢ç ä¸å䏿å°ã |
| | | 7. æ«ææ§ç ä»å¯æ¥è¯¢åæ¹æ¬¡åä½åºä¿¡æ¯ï¼æ«ææ°ç 坿¥è¯¢å½åæ¹æ¬¡ãæçåæ¿æ¢æ¥æºã |
| | | |
| | | ## API |
| | | |
| | | ### 1. ç ´æè¢ç æ¿æ¢ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |---|---|---| |
| | | | POST | `/mes/pro/bag-code/replace` | ä½åºç ´ææ§è¢ç å¹¶å¨åæ¹æ¬¡çæçéæ°è¢ç | |
| | | |
| | | æéï¼`mes:pro-bag-code:replace` |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |---|---|---|---| |
| | | | `batchId` | Long | æ¯ | çäº§æ¹æ¬¡ç¼å· | |
| | | | `oldIds` | Array<Long> | æ¯ | å¾
ä½åºè¢ç ç¼å·ï¼å»éåè³å° 1 个ï¼å次æå¤ 200 个 | |
| | | | `reason` | String | æ¯ | æ¿æ¢åå ï¼ä¾å¦âå
è£
ç ´æâï¼æé¿ 255 个å符 | |
| | | |
| | | **请æ±ç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "batchId": 1001, |
| | | "oldIds": [5001, 5002], |
| | | "reason": "å
è£
ç ´æ" |
| | | } |
| | | ``` |
| | | |
| | | **ååºå段ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |---|---|---| |
| | | | `replaceUuid` | String | æ¬æ¬¡æ¿æ¢ç» UUIDï¼å¯ç¨äºè¯å«æ¬æ¬¡æ°ç éå | |
| | | | `batchId` | Long | çäº§æ¹æ¬¡ç¼å· | |
| | | | `batchCode` | String | çäº§æ¹æ¬¡å· | |
| | | | `count` | Integer | æ¬æ¬¡æ¿æ¢æ°é | |
| | | | `items` | Array | æ°æ§è¢ç æ å° | |
| | | | `items.oldBagCodeId` | Long | æ§è¢ç ç¼å· | |
| | | | `items.oldCode` | String | æ§è¢ç | |
| | | | `items.oldBagNo` | Integer | æ§è¢åºå· | |
| | | | `items.oldStatus` | Integer | ä½åºåç¶æ | |
| | | | `items.oldPalletId` | Long | æ§è¢ç åæçç¼å·ï¼å¯ä¸ºç©º | |
| | | | `items.oldPalletCode` | String | æ§è¢ç åæçç ï¼å¯ä¸ºç©º | |
| | | | `items.newBagCodeId` | Long | æ°è¢ç ç¼å· | |
| | | | `items.newCode` | String | æ°è¢ç | |
| | | | `items.newBagNo` | Integer | æ°è¢åºå· | |
| | | | `items.newPalletId` | Long | æ°è¢ç å½åæçç¼å·ï¼å¯ä¸ºç©º | |
| | | | `items.newPalletCode` | String | æ°è¢ç å½åæçç ï¼å¯ä¸ºç©º | |
| | | | `items.reason` | String | æ¿æ¢åå | |
| | | | `items.replaceTime` | String | æ¿æ¢æ¶é´ | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "replaceUuid": "9f6e4c4b2b2c4d5b8a8a8c0a0b0c0d0e", |
| | | "batchId": 1001, |
| | | "batchCode": "PC20260821L01ITEM001", |
| | | "count": 2, |
| | | "items": [ |
| | | { |
| | | "oldBagCodeId": 5001, |
| | | "oldCode": "PC20260821L01ITEM001-0001", |
| | | "oldBagNo": 1, |
| | | "oldStatus": 20, |
| | | "oldPalletId": 3001, |
| | | "oldPalletCode": "PC20260821L01ITEM001-P01", |
| | | "newBagCodeId": 6001, |
| | | "newCode": "PC20260821L01ITEM001-1201", |
| | | "newBagNo": 1201, |
| | | "newPalletId": 3001, |
| | | "newPalletCode": "PC20260821L01ITEM001-P01", |
| | | "reason": "å
è£
ç ´æ", |
| | | "replaceTime": "2026-08-21 15:30:00" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |---|---|---| |
| | | | `status` | è¢ç å表ãè¢ç 详æ
ãæ«ç 追溯 | 10 å·²çæã20 已导åºå°å·ã30 å·²ä½åº | |
| | | | `cancelTime` | è¢ç 详æ
ãæ«ç 追溯 | ä»
ä½åºè¢ç è¿å | |
| | | | `cancelReason` | è¢ç 详æ
ãæ«ç 追溯 | å±ç¤ºç ´ææå
¶ä»æ¿æ¢åå | |
| | | | `replacementUuid` | è¢ç 详æ
ãæ«ç 追溯 | æ è¯æ¿æ¢æä½ | |
| | | | `replacedByCode` | ä½åºæ§ç 追溯 | å±ç¤ºæ¿æ¢åçæ°è¢ç | |
| | | | `replacementOfCode` | æ°ç 追溯 | å±ç¤ºè¢«æ¿æ¢çæ§è¢ç | |
| | | | `bagQuantity` | æ¹æ¬¡åè¡¨ãæ¹æ¬¡è¯¦æ
| æå½åææè¢ç æ°éç»è®¡ï¼ä¸å
å«å·²ä½åºè¢ç | |
| | | | `palletCode` | è¢ç å表ãæç详æ
ãæ«ç 追溯 | å·²ç»å®å¯ç¨æççæ¿æ¢æ°ç ç»§æ¿åæç | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |---|---| |
| | | | æ®éçæ | ä»ä»
å
许çäº§ä¸æ¹æ¬¡ï¼ä½¿ç¨ `/mes/pro/bag-code/generate` | |
| | | | ç ´ææ¿æ¢ | å
许ç产ä¸ãå·²å®ææ¹æ¬¡ï¼è稿åå·²ä½åºæ¹æ¬¡ä¸å
许 | |
| | | | æ§ç ç¶æ | ä»
å·²çæã已导åºå°å·å¯ä»¥æ¿æ¢ï¼å·²ä½åºä¸è½é夿¿æ¢ | |
| | | | æ¹æ¬¡å½å± | `oldIds` å¿
é¡»å
¨é¨å±äºè¯·æ±ä¸ç `batchId` | |
| | | | æ°ç åºå· | 仿¹æ¬¡å岿大è¢åºå·ç»§ç»éå¢ï¼å·²ä½åºåé»è¾å é¤åºå·ä¹ä¸å¤ç¨ | |
| | | | æ°é | ä½åº N ä¸ªå¹¶çæ N ä¸ªï¼æ¹æ¬¡ææè¢ç æ°éä¿æä¸å | |
| | | | æªè£
æç | æ§ç ä½åºï¼æ°ç ä¿ææªç»å® | |
| | | | å·²è£
æç | åæçå¿
é¡»åå¨ä¸å¯ç¨ï¼æ§ç è§£ç»å¹¶ä½åºï¼æ°ç èªå¨ç»§æ¿åæç | |
| | | | æçæ°é | æ¿æ¢ååæçææç»å®æ°éä¿æä¸å | |
| | | | æå° | æ°ç åå§ä¸ºå·²çæï¼å¯¼åºåå为已导åºå°å·ï¼æ§ç ä¸å¾å¯¼åºæå° | |
| | | | 追溯 | æ§ç è®°å½ä¿çå¹¶æ¾ç¤ºå·²ä½åºï¼ä¸è¿åè¢ç ä¸åå¨ï¼æ°æ§ç å¯äºç¸è¿½æº¯ | |
| | | | ååæ§ | ä½åºãçæãæçç»§æ¿ãæ¿æ¢è®°å½åå
¥ä»»ä¸æ¥å¤±è´¥ï¼å
¨é¨äºå¡åæ» | |
| | | |
| | | ## æ¥å£è°ç¨æ¶åº |
| | | |
| | | 1. è·åè¢ç åé¡µï¼ææ¹æ¬¡åç¶æçéææè¢ç ã |
| | | 2. ç¨æ·å¾éç ´æè¢ç å¹¶å¡«ååå ã |
| | | 3. è°ç¨ `/mes/pro/bag-code/replace`ã |
| | | 4. æååå·æ°è¢ç åè¡¨åæ¹æ¬¡æ°éã |
| | | 5. 便®ååºçæ°è¢ç éåï¼æ `replaceUuid` æ¥è¯¢æå¯¼åºæ°ç è¿è¡æå°ã |
| | | 6. æå°æååå·æ°ç¶æï¼å¦éæ«ç 确认ï¼å嫿«ææ§ç åæ°ç æ ¸å¯¹æ¿æ¢å
³ç³»ã |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `oldIds` ä¸è¦æ··å
¥ä¸åæ¹æ¬¡çè¢ç ï¼æå¡ç«¯ä¼åæ¬¡æ ¡éªã |
| | | - ä¸è¦è°ç¨æ®é `/generate` å®ç°ç ´æè¡¥ç ï¼æ®éçæä¼å¢å è¢ç æ°éä¸ä¸ä¿åæ¿æ¢å
³ç³»ã |
| | | - æ°è¢ç ä¸å¤ç¨æ§è¢ç ç code æè¢åºå·ï¼1200 è¢æ¿æ¢ 2 è¢æ¶æ°ç éå¸¸ä» 1201ã1202 ç»§ç»çæã |
| | | - å·²ä½åºæ§ç ä»å¯è¿½æº¯ï¼ä½ä¸å¯ç»å®æçãä¸å¯åæ¬¡æ¿æ¢ãä¸å¯æå°ã |
| | | - åæçå·²ä½åºæä¸å卿¶ï¼å·²ç»å®è¢ç çæ¿æ¢ä¼å¤±è´¥ï¼éè¦å
å¤çæçç¶æã |
| | | - æ¹æ¬¡è¿½æº¯ä¸çè¢ç 对象å
å«ç¶æå段ï¼å±ç¤ºä½åºæ è¯æ¶ä¸è¦åªæ¾ç¤º `code` å符串ã |
| | | - æ¿æ¢æ¥å£è¿åçæ°ç åå§æªæå°ï¼å¯¼åºæååæå为â已导åºå°å·âã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ä¸è¢ä¸ç ï¼ç ´æè¢ç æ¿æ¢è¿ç§» |
| | | -- 说æï¼æ§è¢ç ä¿çå¹¶æ è®°å·²ä½åºï¼æ°è¢ç 䏿§è¢ç éè¿æ¿æ¢è®°å½å
³èã |
| | | |
| | | SET @cancel_time_exists = ( |
| | | SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_pro_bag_code' AND column_name = 'cancel_time' |
| | | ); |
| | | SET @sql = IF(@cancel_time_exists = 0, |
| | | 'ALTER TABLE mes_pro_bag_code ADD COLUMN cancel_time DATETIME DEFAULT NULL COMMENT ''ä½åºæ¶é´'' AFTER print_time', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; |
| | | EXECUTE stmt; |
| | | DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @cancel_reason_exists = ( |
| | | SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_pro_bag_code' AND column_name = 'cancel_reason' |
| | | ); |
| | | SET @sql = IF(@cancel_reason_exists = 0, |
| | | 'ALTER TABLE mes_pro_bag_code ADD COLUMN cancel_reason VARCHAR(255) DEFAULT NULL COMMENT ''ä½åºåå '' AFTER cancel_time', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; |
| | | EXECUTE stmt; |
| | | DEALLOCATE PREPARE stmt; |
| | | |
| | | CREATE TABLE IF NOT EXISTS `mes_pro_bag_code_replace` ( |
| | | `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `replace_uuid` VARCHAR(32) NOT NULL COMMENT 'æ¿æ¢ç» UUID', |
| | | `batch_id` BIGINT NOT NULL COMMENT 'çäº§æ¹æ¬¡ç¼å·', |
| | | `batch_code` VARCHAR(64) DEFAULT NULL COMMENT 'çäº§æ¹æ¬¡å·', |
| | | `old_bag_code_id` BIGINT NOT NULL COMMENT 'æ§è¢ç ç¼å·', |
| | | `old_code` VARCHAR(64) NOT NULL COMMENT 'æ§è¢ç ', |
| | | `old_bag_no` INT NOT NULL COMMENT 'æ§è¢åºå·', |
| | | `old_status` TINYINT NOT NULL COMMENT 'æ§è¢ç ä½åºåç¶æ', |
| | | `old_pallet_id` BIGINT DEFAULT NULL COMMENT 'æ§è¢ç åæçç¼å·', |
| | | `old_pallet_code` VARCHAR(64) DEFAULT NULL COMMENT 'æ§è¢ç åæçç ', |
| | | `new_bag_code_id` BIGINT NOT NULL COMMENT 'æ°è¢ç ç¼å·', |
| | | `new_code` VARCHAR(64) NOT NULL COMMENT 'æ°è¢ç ', |
| | | `new_bag_no` INT NOT NULL COMMENT 'æ°è¢åºå·', |
| | | `reason` VARCHAR(255) NOT NULL COMMENT 'æ¿æ¢åå ', |
| | | `replace_time` DATETIME NOT NULL COMMENT 'æ¿æ¢æ¶é´', |
| | | `creator` VARCHAR(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` VARCHAR(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`), |
| | | UNIQUE KEY `uk_old_bag_code_id` (`old_bag_code_id`), |
| | | UNIQUE KEY `uk_new_bag_code_id` (`new_bag_code_id`), |
| | | KEY `idx_replace_uuid` (`replace_uuid`), |
| | | KEY `idx_batch_id` (`batch_id`), |
| | | KEY `idx_old_code` (`old_code`), |
| | | KEY `idx_new_code` (`new_code`) |
| | | ) ENGINE = InnoDB COMMENT = 'MES è¢ç æ¿æ¢è®°å½'; |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 602629, 'è¢ç ç ´ææ¿æ¢', 'mes:pro-bag-code:replace', 3, 6, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | FROM DUAL |
| | | WHERE NOT EXISTS (SELECT 1 FROM `system_menu` WHERE `id` = 602629 OR (`permission` = 'mes:pro-bag-code:replace' AND `deleted` = b'0')); |
| | |
| | | `pallet_code` VARCHAR(64) DEFAULT NULL COMMENT 'æçç ï¼åä½ï¼ä¾¿äºå±ç¤ºï¼', |
| | | `status` TINYINT NOT NULL DEFAULT 10 COMMENT 'ç¶æï¼åå
¸ mes_pro_bag_code_statusï¼10 å·²çæ 20 已导åºå°å· 30 å·²ä½åºï¼', |
| | | `print_time` DATETIME DEFAULT NULL COMMENT '导åºï¼äº¤ä»å°å·ï¼æ¶é´', |
| | | `cancel_time` DATETIME DEFAULT NULL COMMENT 'ä½åºæ¶é´', |
| | | `cancel_reason` VARCHAR(255) DEFAULT NULL COMMENT 'ä½åºåå ', |
| | | `remark` VARCHAR(255) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` VARCHAR(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | |
| | | KEY `idx_batch_id` (`batch_id`), |
| | | KEY `idx_uuid` (`uuid`), |
| | | KEY `idx_pallet_id` (`pallet_id`) |
| | | ) ENGINE = InnoDB COMMENT = 'MES è¢ç èµç ï¼ä¸è¢ä¸ç ï¼'; |
| | | ) ENGINE = InnoDB COMMENT = 'MES è¢ç èµç ï¼ä¸è¢ä¸ç ï¼'; |
| | | |
| | | -- ---------------------------- |
| | | -- 5. æ¹æ¬¡å·èªå¨ç¼ç è§åï¼PRO_BATCH_CODE |
| | | -- 5. è¢ç æ¿æ¢è®°å½è¡¨ |
| | | -- ---------------------------- |
| | | CREATE TABLE IF NOT EXISTS `mes_pro_bag_code_replace` ( |
| | | `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `replace_uuid` VARCHAR(32) NOT NULL COMMENT 'æ¿æ¢ç» UUID', |
| | | `batch_id` BIGINT NOT NULL COMMENT 'çäº§æ¹æ¬¡ç¼å·', |
| | | `batch_code` VARCHAR(64) DEFAULT NULL COMMENT 'çäº§æ¹æ¬¡å·', |
| | | `old_bag_code_id` BIGINT NOT NULL COMMENT 'æ§è¢ç ç¼å·', |
| | | `old_code` VARCHAR(64) NOT NULL COMMENT 'æ§è¢ç ', |
| | | `old_bag_no` INT NOT NULL COMMENT 'æ§è¢åºå·', |
| | | `old_status` TINYINT NOT NULL COMMENT 'æ§è¢ç ä½åºåç¶æ', |
| | | `old_pallet_id` BIGINT DEFAULT NULL COMMENT 'æ§è¢ç åæçç¼å·', |
| | | `old_pallet_code` VARCHAR(64) DEFAULT NULL COMMENT 'æ§è¢ç åæçç ', |
| | | `new_bag_code_id` BIGINT NOT NULL COMMENT 'æ°è¢ç ç¼å·', |
| | | `new_code` VARCHAR(64) NOT NULL COMMENT 'æ°è¢ç ', |
| | | `new_bag_no` INT NOT NULL COMMENT 'æ°è¢åºå·', |
| | | `reason` VARCHAR(255) NOT NULL COMMENT 'æ¿æ¢åå ', |
| | | `replace_time` DATETIME NOT NULL COMMENT 'æ¿æ¢æ¶é´', |
| | | `creator` VARCHAR(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` VARCHAR(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`), |
| | | UNIQUE KEY `uk_old_bag_code_id` (`old_bag_code_id`), |
| | | UNIQUE KEY `uk_new_bag_code_id` (`new_bag_code_id`), |
| | | KEY `idx_replace_uuid` (`replace_uuid`), |
| | | KEY `idx_batch_id` (`batch_id`), |
| | | KEY `idx_old_code` (`old_code`), |
| | | KEY `idx_new_code` (`new_code`) |
| | | ) ENGINE = InnoDB COMMENT = 'MES è¢ç æ¿æ¢è®°å½'; |
| | | |
| | | -- ---------------------------- |
| | | -- 6. æ¹æ¬¡å·èªå¨ç¼ç è§åï¼PRO_BATCH_CODE |
| | | -- ç»æï¼åºå®å符(PC) + æ¥æ(yyyyMMdd) + è¾å
¥å符(产线ç¼ç +åç§ç¼ç ) + æµæ°´å·(3ä½ï¼ææ¥å¾ªç¯) |
| | | -- 示ä¾ï¼PC20260818L01NY001 |
| | | -- ---------------------------- |
| | |
| | | (602620, 'çæäºç»´ç æ°æ®å
', 'mes:pro-bag-code:generate', 3, 2, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602621, 'è¢ç å é¤', 'mes:pro-bag-code:delete', 3, 3, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602622, 'è¢ç 导åº', 'mes:pro-bag-code:export', 3, 4, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602623, 'è¢ç ç»å®æç', 'mes:pro-bag-code:bind', 3, 5, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | (602623, 'è¢ç ç»å®æç', 'mes:pro-bag-code:bind', 3, 5, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602629, 'è¢ç ç ´ææ¿æ¢', 'mes:pro-bag-code:replace', 3, 6, 602618, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- æçç 管ç |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | |
| | | 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.MesProBagCodePageReqVO; |
| | | 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; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeTraceRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-bag-code:create')") |
| | | public CommonResult<String> generateBagCodes(@Valid @RequestBody MesProBagCodeGenerateReqVO generateReqVO) { |
| | | return success(bagCodeService.generateBagCodes(generateReqVO)); |
| | | } |
| | | |
| | | @PostMapping("/replace") |
| | | @Operation(summary = "ä½åºç ´æè¢ç å¹¶çæçéæ¿æ¢è¢ç ") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-bag-code:replace')") |
| | | public CommonResult<MesProBagCodeReplaceRespVO> replaceBagCodes( |
| | | @Valid @RequestBody MesProBagCodeReplaceReqVO replaceReqVO) { |
| | | return success(bagCodeService.replaceBagCodes(replaceReqVO)); |
| | | } |
| | | |
| | | @DeleteMapping("/delete-by-uuid") |
| | |
| | | |
| | | private MesProBagCodeTraceRespVO buildBagCodeTraceRespVO(MesProBagCodeDO bagCode) { |
| | | MesProBagCodeTraceRespVO respVO = BeanUtils.toBean(bagCode, MesProBagCodeTraceRespVO.class); |
| | | var replacement = bagCode.getStatus() != null |
| | | && bagCode.getStatus().equals(cn.iocoder.yudao.module.mes.enums.pro.MesProBagCodeStatusEnum.CANCELED.getStatus()) |
| | | ? bagCodeService.getReplacementByOldBagCodeId(bagCode.getId()) |
| | | : bagCodeService.getReplacementByNewBagCodeId(bagCode.getId()); |
| | | if (replacement != null) { |
| | | respVO.setReplacementUuid(replacement.getReplaceUuid()); |
| | | if (bagCode.getId().equals(replacement.getOldBagCodeId())) { |
| | | respVO.setReplacedByCode(replacement.getNewCode()); |
| | | } else { |
| | | respVO.setReplacementOfCode(replacement.getOldCode()); |
| | | } |
| | | } |
| | | // æ¹æ¬¡ä¿¡æ¯ |
| | | MesProBatchDO batch = batchService.getBatch(bagCode.getBatchId()); |
| | | if (batch != null) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES è¢ç æ¿æ¢æç» Response VO") |
| | | @Data |
| | | public class MesProBagCodeReplaceItemRespVO { |
| | | |
| | | @Schema(description = "æ§è¢ç ç¼å·") |
| | | private Long oldBagCodeId; |
| | | |
| | | @Schema(description = "æ§è¢ç ") |
| | | private String oldCode; |
| | | |
| | | @Schema(description = "æ§è¢åºå·") |
| | | private Integer oldBagNo; |
| | | |
| | | @Schema(description = "æ§è¢ç ä½åºåç¶æ") |
| | | private Integer oldStatus; |
| | | |
| | | @Schema(description = "æ§è¢ç åæçç¼å·") |
| | | private Long oldPalletId; |
| | | |
| | | @Schema(description = "æ§è¢ç åæçç ") |
| | | private String oldPalletCode; |
| | | |
| | | @Schema(description = "æ°è¢ç ç¼å·") |
| | | private Long newBagCodeId; |
| | | |
| | | @Schema(description = "æ°è¢ç ") |
| | | private String newCode; |
| | | |
| | | @Schema(description = "æ°è¢åºå·") |
| | | private Integer newBagNo; |
| | | |
| | | @Schema(description = "æ°è¢ç å½åæçç¼å·") |
| | | private Long newPalletId; |
| | | |
| | | @Schema(description = "æ°è¢ç å½åæçç ") |
| | | private String newPalletCode; |
| | | |
| | | @Schema(description = "æ¿æ¢åå ") |
| | | private String reason; |
| | | |
| | | @Schema(description = "æ¿æ¢æ¶é´") |
| | | private LocalDateTime replaceTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES ç ´æè¢ç æ¿æ¢ Request VO") |
| | | @Data |
| | | public class MesProBagCodeReplaceReqVO { |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "çäº§æ¹æ¬¡ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "å¾
ä½åºçè¢ç ç¼å·å表", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotEmpty(message = "å¾
ä½åºè¢ç ä¸è½ä¸ºç©º") |
| | | @Size(max = 200, message = "忬¡æå¤æ¿æ¢ 200 个è¢ç ") |
| | | private List<Long> oldIds; |
| | | |
| | | @Schema(description = "æ¿æ¢åå ", requiredMode = Schema.RequiredMode.REQUIRED, example = "å
è£
ç ´æ") |
| | | @NotBlank(message = "æ¿æ¢åå ä¸è½ä¸ºç©º") |
| | | @Size(max = 255, message = "æ¿æ¢åå é¿åº¦ä¸è½è¶
è¿ 255 个å符") |
| | | private String reason; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES ç ´æè¢ç æ¿æ¢ Response VO") |
| | | @Data |
| | | public class MesProBagCodeReplaceRespVO { |
| | | |
| | | @Schema(description = "æ¬æ¬¡æ¿æ¢ç» UUID") |
| | | private String replaceUuid; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡ç¼å·") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡å·") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "æ¿æ¢æ°é") |
| | | private Integer count; |
| | | |
| | | @Schema(description = "æ¿æ¢æç»") |
| | | private List<MesProBagCodeReplaceItemRespVO> items; |
| | | |
| | | } |
| | |
| | | @ColumnWidth(20) |
| | | private LocalDateTime printTime; |
| | | |
| | | @Schema(description = "ä½åºæ¶é´") |
| | | @ExcelIgnore |
| | | private LocalDateTime cancelTime; |
| | | |
| | | @Schema(description = "ä½åºåå ") |
| | | @ExcelIgnore |
| | | private String cancelReason; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | @ExcelIgnore |
| | | private String remark; |
| | |
| | | @Schema(description = "导åºï¼äº¤ä»å°å·ï¼æ¶é´") |
| | | private LocalDateTime printTime; |
| | | |
| | | @Schema(description = "ä½åºæ¶é´") |
| | | private LocalDateTime cancelTime; |
| | | |
| | | @Schema(description = "ä½åºåå ") |
| | | private String cancelReason; |
| | | |
| | | @Schema(description = "æ¿æ¢ç» UUID") |
| | | private String replacementUuid; |
| | | |
| | | @Schema(description = "æ¿æ¢åçæ°è¢ç ") |
| | | private String replacedByCode; |
| | | |
| | | @Schema(description = "è¢«æ¿æ¢çæ§è¢ç ") |
| | | private String replacementOfCode; |
| | | |
| | | // ========== æ¹æ¬¡ä¿¡æ¯ ========== |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡ç¼å·", example = "1024") |
| | |
| | | */ |
| | | private LocalDateTime printTime; |
| | | /** |
| | | * ä½åºæ¶é´ |
| | | */ |
| | | private LocalDateTime cancelTime; |
| | | /** |
| | | * ä½åºåå |
| | | */ |
| | | private String cancelReason; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @TableName("mes_pro_bag_code_replace") |
| | | @KeySequence("mes_pro_bag_code_replace_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class MesProBagCodeReplaceDO extends BaseDO { |
| | | |
| | | @TableId |
| | | private Long id; |
| | | private String replaceUuid; |
| | | private Long batchId; |
| | | private String batchCode; |
| | | private Long oldBagCodeId; |
| | | private String oldCode; |
| | | private Integer oldBagNo; |
| | | private Integer oldStatus; |
| | | private Long oldPalletId; |
| | | private String oldPalletCode; |
| | | private Long newBagCodeId; |
| | | private String newCode; |
| | | private Integer newBagNo; |
| | | private String reason; |
| | | private LocalDateTime replaceTime; |
| | | |
| | | } |
| | |
| | | @Select("SELECT IFNULL(MAX(bag_no), 0) FROM mes_pro_bag_code WHERE batch_id = #{batchId}") |
| | | Integer selectMaxBagNo(@Param("batchId") Long batchId); |
| | | |
| | | default List<MesProBagCodeDO> selectListByIdsForUpdate(Collection<Long> ids) { |
| | | return selectList(new LambdaQueryWrapperX<MesProBagCodeDO>() |
| | | .in(MesProBagCodeDO::getId, ids) |
| | | .orderByAsc(MesProBagCodeDO::getId) |
| | | .last("FOR UPDATE")); |
| | | } |
| | | |
| | | @Update("<script>UPDATE mes_pro_bag_code SET status = #{toStatus}, cancel_time = #{cancelTime}, " + |
| | | "cancel_reason = #{cancelReason}, pallet_id = NULL, pallet_code = NULL, update_time = NOW() " + |
| | | "WHERE deleted = 0 AND id = #{id} AND status = #{fromStatus}</script>") |
| | | int cancelById(@Param("id") Long id, @Param("fromStatus") Integer fromStatus, |
| | | @Param("toStatus") Integer toStatus, @Param("cancelTime") LocalDateTime cancelTime, |
| | | @Param("cancelReason") String cancelReason); |
| | | |
| | | @Select("SELECT COUNT(*) FROM mes_pro_bag_code WHERE batch_id = #{batchId} " + |
| | | "AND deleted = 0 AND status <> 30") |
| | | int selectEffectiveCountByBatchId(@Param("batchId") Long batchId); |
| | | |
| | | /** |
| | | * æ¹éæ 记为已导åºå°å·ï¼ä»
æ´æ°å¤äºç®æ åç¶æçè®°å½ï¼ |
| | | * |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeReplaceDO; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | @Mapper |
| | | public interface MesProBagCodeReplaceMapper extends BaseMapperX<MesProBagCodeReplaceDO> { |
| | | |
| | | default List<MesProBagCodeReplaceDO> selectListByOldBagCodeIds(Collection<Long> oldBagCodeIds) { |
| | | return selectList(new LambdaQueryWrapper<MesProBagCodeReplaceDO>() |
| | | .in(MesProBagCodeReplaceDO::getOldBagCodeId, oldBagCodeIds)); |
| | | } |
| | | |
| | | default MesProBagCodeReplaceDO selectByOldBagCodeId(Long oldBagCodeId) { |
| | | return selectOne(MesProBagCodeReplaceDO::getOldBagCodeId, oldBagCodeId); |
| | | } |
| | | |
| | | default MesProBagCodeReplaceDO selectByNewBagCodeId(Long newBagCodeId) { |
| | | return selectOne(MesProBagCodeReplaceDO::getNewBagCodeId, newBagCodeId); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Select; |
| | | |
| | | /** |
| | | * MES çäº§æ¹æ¬¡ Mapper |
| | |
| | | return selectCount(MesProBatchDO::getLineId, lineId); |
| | | } |
| | | |
| | | @Select("SELECT * FROM mes_pro_batch WHERE id = #{id} AND deleted = 0 FOR UPDATE") |
| | | MesProBatchDO selectByIdForUpdate(@org.apache.ibatis.annotations.Param("id") Long id); |
| | | |
| | | default PageResult<MesProBatchDO> selectPage(MesProBatchPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesProBatchDO>() |
| | | .likeIfPresent(MesProBatchDO::getCode, reqVO.getCode()) |
| | |
| | | return selectOne(MesProPalletDO::getCode, code); |
| | | } |
| | | |
| | | @Select("SELECT * FROM mes_pro_pallet WHERE id = #{id} AND deleted = 0 FOR UPDATE") |
| | | MesProPalletDO selectByIdForUpdate(@Param("id") Long id); |
| | | |
| | | default List<MesProPalletDO> selectListByBatchId(Long batchId) { |
| | | return selectList(MesProPalletDO::getBatchId, batchId); |
| | | } |
| | |
| | | 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, "è¢ç åæçä¸å卿已ä½åºï¼ä¸å
许继æ¿"); |
| | | |
| | | // ========== MES ç产管ç-æçç ï¼1-040-753-000ï¼ ========== |
| | | ErrorCode PRO_PALLET_NOT_EXISTS = new ErrorCode(1_040_753_000, "æçç ä¸åå¨"); |
| | |
| | | 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.MesProBagCodePageReqVO; |
| | | 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; |
| | | import jakarta.validation.Valid; |
| | | |
| | |
| | | * @return çæç» UUIDï¼æ è®°å䏿¬¡çæçæ°æ®å
ï¼ |
| | | */ |
| | | String generateBagCodes(@Valid MesProBagCodeGenerateReqVO generateReqVO); |
| | | |
| | | /** |
| | | * ä½åºç ´æè¢ç å¹¶å¨åæ¹æ¬¡çæçéæ¿æ¢è¢ç |
| | | */ |
| | | MesProBagCodeReplaceRespVO replaceBagCodes(@Valid MesProBagCodeReplaceReqVO replaceReqVO); |
| | | |
| | | /** |
| | | * å é¤çæç»ï¼ä»
"å·²çæ"ç¶æä¸æªç»å®æççè¢ç å
许å é¤ï¼ |
| | |
| | | MesProBagCodeDO getBagCodeByCode(String code); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¢ç æ¿æ¢è®°å½ |
| | | */ |
| | | cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeReplaceDO getReplacementByOldBagCodeId(Long oldBagCodeId); |
| | | |
| | | cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeReplaceDO getReplacementByNewBagCodeId(Long newBagCodeId); |
| | | |
| | | /** |
| | | * è·å¾è¢ç å页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | |
| | | 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.MesProBagCodePageReqVO; |
| | | 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.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.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.bagcode.MesProBagCodeReplaceMapper; |
| | | 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 cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | private MesProBagCodeMapper bagCodeMapper; |
| | | @Resource |
| | | private MesProBatchMapper batchMapper; |
| | | @Resource |
| | | private MesProBagCodeReplaceMapper replaceMapper; |
| | | @Resource |
| | | private MesProPalletMapper palletMapper; |
| | | |
| | | @Resource |
| | | private MesProPalletService palletService; |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public String generateBagCodes(MesProBagCodeGenerateReqVO generateReqVO) { |
| | | // 1. æ ¡éªæ¹æ¬¡åå¨ä¸å¤äºç产ä¸ç¶æ |
| | | MesProBatchDO batch = batchMapper.selectById(generateReqVO.getBatchId()); |
| | | MesProBatchDO batch = batchMapper.selectByIdForUpdate(generateReqVO.getBatchId()); |
| | | if (batch == null) { |
| | | throw exception(PRO_BATCH_NOT_EXISTS); |
| | | } |
| | |
| | | .setBagQuantity((batch.getBagQuantity() == null ? 0 : batch.getBagQuantity()) |
| | | + generateReqVO.getCount())); |
| | | return uuid; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesProBagCodeReplaceRespVO replaceBagCodes(MesProBagCodeReplaceReqVO replaceReqVO) { |
| | | MesProBatchDO batch = batchMapper.selectByIdForUpdate(replaceReqVO.getBatchId()); |
| | | if (batch == null) { |
| | | throw exception(PRO_BATCH_NOT_EXISTS); |
| | | } |
| | | if (!MesProBatchStatusEnum.PRODUCING.getStatus().equals(batch.getStatus()) |
| | | && !MesProBatchStatusEnum.FINISHED.getStatus().equals(batch.getStatus())) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_BATCH_STATUS_INVALID); |
| | | } |
| | | |
| | | List<Long> oldIds = replaceReqVO.getOldIds().stream() |
| | | .distinct().sorted().toList(); |
| | | List<MesProBagCodeDO> oldBagCodes = bagCodeMapper.selectListByIdsForUpdate(oldIds); |
| | | if (oldBagCodes.size() != oldIds.size()) { |
| | | throw exception(PRO_BAG_CODE_NOT_EXISTS); |
| | | } |
| | | for (MesProBagCodeDO oldBagCode : oldBagCodes) { |
| | | if (!batch.getId().equals(oldBagCode.getBatchId())) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_BATCH_MISMATCH); |
| | | } |
| | | if (!MesProBagCodeStatusEnum.GENERATED.getStatus().equals(oldBagCode.getStatus()) |
| | | && !MesProBagCodeStatusEnum.PRINTED.getStatus().equals(oldBagCode.getStatus())) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_STATUS_INVALID); |
| | | } |
| | | if (replaceMapper.selectByOldBagCodeId(oldBagCode.getId()) != null) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_ALREADY_REPLACED); |
| | | } |
| | | } |
| | | |
| | | Map<Long, MesProPalletDO> palletMap = new LinkedHashMap<>(); |
| | | oldBagCodes.stream().map(MesProBagCodeDO::getPalletId).filter(id -> id != null) |
| | | .distinct().sorted().forEach(palletId -> { |
| | | MesProPalletDO pallet = palletMapper.selectByIdForUpdate(palletId); |
| | | if (pallet == null || !MesProPalletStatusEnum.IN_USE.getStatus().equals(pallet.getStatus())) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_PALLET_INVALID); |
| | | } |
| | | palletMap.put(palletId, pallet); |
| | | }); |
| | | |
| | | String replaceUuid = IdUtil.fastSimpleUUID(); |
| | | LocalDateTime replaceTime = LocalDateTime.now(); |
| | | int startNo = bagCodeMapper.selectMaxBagNo(batch.getId()) + 1; |
| | | List<MesProBagCodeDO> newBagCodes = new ArrayList<>(oldBagCodes.size()); |
| | | List<MesProBagCodeReplaceDO> replacements = new ArrayList<>(oldBagCodes.size()); |
| | | List<MesProBagCodeReplaceItemRespVO> items = new ArrayList<>(oldBagCodes.size()); |
| | | for (int i = 0; i < oldBagCodes.size(); i++) { |
| | | MesProBagCodeDO oldBagCode = oldBagCodes.get(i); |
| | | if (bagCodeMapper.cancelById(oldBagCode.getId(), oldBagCode.getStatus(), |
| | | MesProBagCodeStatusEnum.CANCELED.getStatus(), replaceTime, replaceReqVO.getReason()) != 1) { |
| | | throw exception(PRO_BAG_CODE_REPLACE_STATUS_INVALID); |
| | | } |
| | | int newBagNo = startNo + i; |
| | | MesProPalletDO pallet = oldBagCode.getPalletId() == null ? null : palletMap.get(oldBagCode.getPalletId()); |
| | | MesProBagCodeDO newBagCode = new MesProBagCodeDO() |
| | | .setUuid(replaceUuid) |
| | | .setCode(batch.getCode() + "-" + StrUtil.padPre(String.valueOf(newBagNo), 4, '0')) |
| | | .setBagNo(newBagNo) |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setPalletId(pallet == null ? null : pallet.getId()) |
| | | .setPalletCode(pallet == null ? null : pallet.getCode()) |
| | | .setStatus(MesProBagCodeStatusEnum.GENERATED.getStatus()) |
| | | .setRemark(replaceReqVO.getReason()); |
| | | newBagCodes.add(newBagCode); |
| | | |
| | | replacements.add(new MesProBagCodeReplaceDO() |
| | | .setReplaceUuid(replaceUuid) |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setOldBagCodeId(oldBagCode.getId()) |
| | | .setOldCode(oldBagCode.getCode()) |
| | | .setOldBagNo(oldBagCode.getBagNo()) |
| | | .setOldStatus(oldBagCode.getStatus()) |
| | | .setOldPalletId(oldBagCode.getPalletId()) |
| | | .setOldPalletCode(oldBagCode.getPalletCode()) |
| | | .setNewCode(newBagCode.getCode()) |
| | | .setNewBagNo(newBagNo) |
| | | .setReason(replaceReqVO.getReason()) |
| | | .setReplaceTime(replaceTime)); |
| | | items.add(new MesProBagCodeReplaceItemRespVO() |
| | | .setOldBagCodeId(oldBagCode.getId()) |
| | | .setOldCode(oldBagCode.getCode()) |
| | | .setOldBagNo(oldBagCode.getBagNo()) |
| | | .setOldStatus(oldBagCode.getStatus()) |
| | | .setOldPalletId(oldBagCode.getPalletId()) |
| | | .setOldPalletCode(oldBagCode.getPalletCode()) |
| | | .setNewCode(newBagCode.getCode()) |
| | | .setNewBagNo(newBagNo) |
| | | .setNewPalletId(newBagCode.getPalletId()) |
| | | .setNewPalletCode(newBagCode.getPalletCode()) |
| | | .setReason(replaceReqVO.getReason()) |
| | | .setReplaceTime(replaceTime)); |
| | | } |
| | | bagCodeMapper.insertBatch(newBagCodes); |
| | | for (int i = 0; i < replacements.size(); i++) { |
| | | replacements.get(i).setNewBagCodeId(newBagCodes.get(i).getId()); |
| | | items.get(i).setNewBagCodeId(newBagCodes.get(i).getId()); |
| | | } |
| | | replaceMapper.insertBatch(replacements); |
| | | batchMapper.updateById(new MesProBatchDO().setId(batch.getId()) |
| | | .setBagQuantity(bagCodeMapper.selectEffectiveCountByBatchId(batch.getId()))); |
| | | |
| | | return new MesProBagCodeReplaceRespVO() |
| | | .setReplaceUuid(replaceUuid) |
| | | .setBatchId(batch.getId()) |
| | | .setBatchCode(batch.getCode()) |
| | | .setCount(newBagCodes.size()) |
| | | .setItems(items); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public MesProBagCodeReplaceDO getReplacementByOldBagCodeId(Long oldBagCodeId) { |
| | | return replaceMapper.selectByOldBagCodeId(oldBagCodeId); |
| | | } |
| | | |
| | | @Override |
| | | public MesProBagCodeReplaceDO getReplacementByNewBagCodeId(Long newBagCodeId) { |
| | | return replaceMapper.selectByNewBagCodeId(newBagCodeId); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesProBagCodeDO> getBagCodePage(MesProBagCodePageReqVO pageReqVO) { |
| | | return bagCodeMapper.selectPage(pageReqVO); |
| | | } |