| doc/产品领用归还模块-前端对接文档.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/inventoryManagement/productBorrow.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/inventoryManagement/stockInventory.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/basicData/product/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/stockManagement/OfficeRecord.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/stockManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
doc/²úÆ·ÁìÓù黹ģ¿é-ǰ¶Ë¶Ô½ÓÎĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,694 @@ # 产åé¢ç¨å½è¿æ¨¡å - åç«¯å¯¹æ¥ææ¡£ ## ä¸ãæ¨¡åæ¦è¿° 产åé¢ç¨å½è¿æ¨¡åç¨äºç®¡ç产åçé¢ç¨åå½è¿æµç¨ï¼ - **é¢ç¨**ï¼æ°å¢é¢ç¨æ¶èªå¨å®æåºåºæä½ï¼èªå¨å®¡æ¹éè¿ï¼åæ¶å®¡æ¹æµç¨ - **å½è¿**ï¼æ°å¢å½è¿æ¶èªå¨å®æå ¥åºæä½ï¼èªå¨å®¡æ¹éè¿ **注æ**ï¼æææ¥å£ç»ä¸ä½¿ç¨ POST æ¹å¼ --- ## äºãAPI æ¥å£è¯´æ ### 1. 产åé¢ç¨æ¥å£ #### 1.1 å页æ¥è¯¢é¢ç¨è®°å½ **请æ±** ``` POST /productBorrow/listPage Content-Type: application/json ``` **请æ±ä½** ```json { "current": 1, // å½å页ç ï¼é»è®¤1 "size": 10, // æ¯é¡µæ¡æ°ï¼é»è®¤10 "borrowNo": "LY202605260001", // éå¡«ï¼é¢ç¨åå·ï¼æ¨¡ç³æ¥è¯¢ "productModelId": 100, // éå¡«ï¼äº§åè§æ ¼ID "borrowerId": 1, // éå¡«ï¼é¢ç¨äººID "borrowerName": "å¼ ä¸", // éå¡«ï¼é¢ç¨äººå§åï¼æ¨¡ç³æ¥è¯¢ "approvalStatus": 0, // éå¡«ï¼å®¡æ¹ç¶æï¼0å¾ å®¡æ¹/1å·²éè¿/2已驳å "status": 0 // éå¡«ï¼å½è¿ç¶æï¼0æªå½è¿/1é¨åå½è¿/2å·²å ¨é¨å½è¿ } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå", "data": { "records": [ { "id": 1, "borrowNo": "LY202605260001", "productModelId": 100, "batchNo": "20260526-ABC001-001", "borrowQuantity": 10.0000, "returnedQuantity": 5.0000, "borrowerId": 1, "borrowerName": "å¼ ä¸", "borrowTime": "2026-05-26 10:00:00", "expectedReturnTime": "2026-06-26 10:00:00", "approvalStatus": 1, "approvalStatusName": "å·²éè¿", "status": 1, "statusName": "é¨åå½è¿", "remark": "项ç®ä½¿ç¨", "productName": "èºä¸å", "model": "M6", "productCode": "LSD-M6", "unit": "æ", "remainingQuantity": 5.0000, "createTime": "2026-05-26 09:00:00" } ], "total": 100, "size": 10, "current": 1, "pages": 10 } } ``` #### 1.2 æ¥è¯¢é¢ç¨è®°å½è¯¦æ **请æ±** ``` POST /productBorrow/getDetail Content-Type: application/json ``` **请æ±ä½** ```json { "id": 1 // å¿ å¡«ï¼é¢ç¨è®°å½ID } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå", "data": { "id": 1, "borrowNo": "LY202605260001", "productModelId": 100, "batchNo": "20260526-ABC001-001", "borrowQuantity": 10.0000, "returnedQuantity": 5.0000, "remainingQuantity": 5.0000, "borrowerId": 1, "borrowerName": "å¼ ä¸", "borrowTime": "2026-05-26 10:00:00", "expectedReturnTime": "2026-06-26 10:00:00", "approvalStatus": 1, "approvalStatusName": "å·²éè¿", "status": 1, "statusName": "é¨åå½è¿", "remark": "项ç®ä½¿ç¨", "productName": "èºä¸å", "model": "M6", "productCode": "LSD-M6", "unit": "æ" } } ``` #### 1.3 æ°å¢é¢ç¨è®°å½ **请æ±** ``` POST /productBorrow/add Content-Type: application/json ``` **请æ±ä½** ```json { "productModelId": 100, // å¿ å¡«ï¼äº§åè§æ ¼ID "batchNo": "20260526-ABC001-001", // éå¡«ï¼æ¹å·ï¼ä¸å¡«å使ç¨é»è®¤æ¹å· "borrowQuantity": 10.0000, // å¿ å¡«ï¼é¢ç¨æ°é "borrowerId": 1, // å¿ å¡«ï¼é¢ç¨äººIDï¼ç³»ç»ç¨æ·IDï¼ "borrowerName": "å¼ ä¸", // å¿ å¡«ï¼é¢ç¨äººå§å "expectedReturnTime": "2026-06-26 10:00:00", // éå¡«ï¼é¢è®¡å½è¿æ¶é´ "remark": "项ç®ä½¿ç¨" // éå¡«ï¼å¤æ³¨ } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå" } ``` **èªå¨æ§è¡çæä½**ï¼ - èªå¨çæé¢ç¨åå·ï¼æ ¼å¼ï¼LY + å¹´ææ¥ + 4ä½åºå·ï¼ - èªå¨å建åºåºè®°å½ - èªå¨å®¡æ ¸éè¿ - èªå¨æ£ååºå - ç¶æç´æ¥è®¾ä¸º"å·²éè¿" #### 1.4 ä¿®æ¹é¢ç¨è®°å½ **请æ±** ``` POST /productBorrow/update Content-Type: application/json ``` **请æ±ä½** ```json { "id": 1, // å¿ å¡«ï¼é¢ç¨è®°å½ID "productModelId": 100, "batchNo": "20260526-ABC001-001", "borrowQuantity": 15.0000, "borrowerId": 1, "borrowerName": "å¼ ä¸", "expectedReturnTime": "2026-06-26 10:00:00", "remark": "项ç®ä½¿ç¨" } ``` **注æ**ï¼åªæå¾ 审æ¹ç¶æï¼approvalStatus=0ï¼çè®°å½æè½ä¿®æ¹ #### 1.5 å é¤é¢ç¨è®°å½ **请æ±** ``` POST /productBorrow/delete Content-Type: application/json ``` **请æ±ä½** ```json [1, 2, 3] // è¦å é¤çè®°å½IDæ°ç» ``` **注æ**ï¼åªæå¾ 审æ¹ç¶æçè®°å½æè½å é¤ #### 1.6 æ¹é审æ¹é¢ç¨è®°å½ **请æ±** ``` POST /productBorrow/approve Content-Type: application/json ``` **请æ±ä½** ```json { "ids": [1, 2, 3], // å¿ å¡«ï¼è¦å®¡æ¹çè®°å½IDæ°ç» "approvalStatusParam": 1 // å¿ å¡«ï¼å®¡æ¹ç¶æï¼1éè¿/2驳å } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå" } ``` --- ### 2. 产åå½è¿æ¥å£ #### 2.1 å页æ¥è¯¢å½è¿è®°å½ **请æ±** ``` POST /productBorrowReturn/listPage Content-Type: application/json ``` **请æ±ä½** ```json { "current": 1, // å½å页ç "size": 10, // æ¯é¡µæ¡æ° "borrowId": 1, // éå¡«ï¼é¢ç¨è®°å½ID "productModelId": 100, // éå¡«ï¼äº§åè§æ ¼ID "returnerId": 2, // éå¡«ï¼å½è¿äººID "returnerName": "æå" // éå¡«ï¼å½è¿äººå§å } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå", "data": { "records": [ { "id": 1, "borrowId": 1, "borrowNo": "LY202605260001", "productModelId": 100, "batchNo": "20260526-ABC001-001", "returnQuantity": 5.0000, "returnerId": 2, "returnerName": "æå", "returnTime": "2026-05-28 14:00:00", "remark": "项ç®ç»æå½è¿", "productName": "èºä¸å", "model": "M6", "productCode": "LSD-M6", "unit": "æ", "borrowQuantity": 10.0000, "borrowerName": "å¼ ä¸" } ], "total": 50, "size": 10, "current": 1, "pages": 5 } } ``` #### 2.2 æ¥è¯¢æä¸ªé¢ç¨è®°å½çå½è¿è®°å½ **请æ±** ``` POST /productBorrowReturn/listByBorrowId Content-Type: application/json ``` **请æ±ä½** ```json { "current": 1, // å½å页ç "size": 10, // æ¯é¡µæ¡æ° "borrowId": 1 // å¿ å¡«ï¼é¢ç¨è®°å½ID } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå", "data": { "records": [...], "total": 5, "size": 10, "current": 1, "pages": 1 } } ``` #### 2.3 æ°å¢å½è¿è®°å½ **请æ±** ``` POST /productBorrowReturn/add Content-Type: application/json ``` **请æ±ä½** ```json { "borrowId": 1, // å¿ å¡«ï¼é¢ç¨è®°å½ID "returnQuantity": 5.0000, // å¿ å¡«ï¼å½è¿æ°é "returnerId": 2, // å¿ å¡«ï¼å½è¿äººIDï¼ç³»ç»ç¨æ·IDï¼ "returnerName": "æå", // å¿ å¡«ï¼å½è¿äººå§å "remark": "项ç®ç»æå½è¿" // éå¡«ï¼å¤æ³¨ } ``` **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå" } ``` **èªå¨æ§è¡çæä½**ï¼ - èªå¨åå»ºå ¥åºè®°å½ - èªå¨å®¡æ ¸éè¿ - èªå¨å¢å åºå - èªå¨æ´æ°é¢ç¨è®°å½çå·²å½è¿æ°éåç¶æ **é误æ åµ**ï¼ ```json { "code": 500, "msg": "å½è¿æ°éä¸è½å¤§äºå©ä½å¯å½è¿æ°éï¼5.0000" } ``` --- ### 3. åºååé¢ç¨éæ¥è¯¢æ¥å£ #### 3.1 å页æ¥è¯¢äº§ååºååé¢ç¨é **æ¥å£è¯´æ**ï¼ - 以"产åè§æ ¼ + æ¹å·"ä¸ºä¸æ¡è®°å½ - æ¾ç¤ºæ¯ä¸ªæ¹å·çåºåæ°éå被é¢ç¨é - ç¨äºé¢ç¨æ¶éæ©äº§ååæ¹å·ï¼æ¥çå¯é¢ç¨æ°é **请æ±** ``` POST /stockInventory/pageStockAndBorrow Content-Type: application/json ``` **请æ±ä½** ```json { "current": 1, // å½å页ç "size": 10, // æ¯é¡µæ¡æ° "topParentProductId": 277, // å¿ å¡«ï¼é¡¶é¨ç¶äº§åIDï¼äº§ååç±»IDï¼ "productName": "èºä¸å", // éå¡«ï¼äº§ååç§°ï¼æ¨¡ç³æ¥è¯¢ "model": "M6", // éå¡«ï¼è§æ ¼åå·ï¼æ¨¡ç³æ¥è¯¢ "batchNo": "20260526" // éå¡«ï¼æ¹å·ï¼æ¨¡ç³æ¥è¯¢ } ``` **åæ°è¯´æ**ï¼ | åæ°å | ç±»å | å¿ å¡« | 说æ | |--------|------|------|------| | current | Integer | å¦ | å½å页ç ï¼é»è®¤1 | | size | Integer | å¦ | æ¯é¡µæ¡æ°ï¼é»è®¤10 | | topParentProductId | Long | æ¯ | é¡¶é¨ç¶äº§åIDï¼äº§ååç±»æ æ ¹èç¹IDï¼ï¼ç¨äºçé产ååç±» | | productName | String | å¦ | 产ååç§°ï¼æ¨¡ç³æ¥è¯¢ | | model | String | å¦ | è§æ ¼åå·ï¼æ¨¡ç³æ¥è¯¢ | | batchNo | String | å¦ | æ¹å·ï¼æ¨¡ç³æ¥è¯¢ | **ååºç¤ºä¾** ```json { "code": 200, "msg": "æä½æå", "data": { "records": [ { "productModelId": 100, "model": "M6", "productCode": "LSD-M6", "unit": "æ", "productName": "èºä¸å", "productId": 50, "batchNo": "20260526-ABC001-001", "qualitity": 100.0000, "lockedQuantity": 5.0000, "borrowedQuantity": 10.0000, "availableQuantity": 90.0000 }, { "productModelId": 100, "model": "M6", "productCode": "LSD-M6", "unit": "æ", "productName": "èºä¸å", "productId": 50, "batchNo": "20260527-ABC001-001", "qualitity": 50.0000, "lockedQuantity": 0, "borrowedQuantity": 0, "availableQuantity": 50.0000 } ], "total": 20, "size": 10, "current": 1, "pages": 2 } } ``` **ååºå段说æ**ï¼ | åæ®µå | ç±»å | 说æ | |--------|------|------| | productModelId | Long | 产åè§æ ¼IDï¼ç¨äºé¢ç¨æ¶ä¼ éï¼ | | model | String | è§æ ¼åå· | | productCode | String | 产åç¼ç | | unit | String | åä½ | | productName | String | 产ååç§° | | productId | Long | 产åID | | batchNo | String | æ¹å·ï¼ç¨äºé¢ç¨æ¶ä¼ éï¼å¯ä¸ºnullï¼ | | qualitity | BigDecimal | å½ååºåæ°é | | lockedQuantity | BigDecimal | å»ç»/é宿°é | | borrowedQuantity | BigDecimal | 被é¢ç¨ä¸æªå½è¿çæ°é | | availableQuantity | BigDecimal | å¯é¢ç¨æ°é = åºåæ°é - 被é¢ç¨æ°é | **计ç®å ¬å¼**ï¼ ``` å¯é¢ç¨æ°é(availableQuantity) = åºåæ°é(qualitity) - 被é¢ç¨é(borrowedQuantity) ``` **被é¢ç¨é计ç®é»è¾**ï¼ - åªç»è®¡å®¡æ¹éè¿çé¢ç¨è®°å½ï¼approval_status = 1ï¼ - åªç»è®¡æªå ¨é¨å½è¿çè®°å½ï¼status != 2ï¼ - 计ç®å ¬å¼ï¼é¢ç¨æ°é - å·²å½è¿æ°é - æäº§åè§æ ¼ID + æ¹å·åç»ç»è®¡ **使ç¨åºæ¯**ï¼ 1. **é¢ç¨éæ©äº§å**ï¼ - è°ç¨æ¤æ¥å£æ¥è¯¢åºå - ç¨æ·éæ©äº§ååæ¹å· - æ¾ç¤ºå¯é¢ç¨æ°éä¾åè - é¢ç¨æ¶ä¼ é `productModelId` å `batchNo` 2. **å端æ¾ç¤ºå»ºè®®**ï¼ - å表æ¾ç¤ºï¼äº§ååç§°ãè§æ ¼åå·ãæ¹å·ãåºåæ°éã被é¢ç¨éãå¯é¢ç¨é - å¯é¢ç¨æ°é为0æè´æ°çè®°å½å¯ä»¥æ 红æç¦ç¨éæ© - æ¯ææäº§ååç§°ãè§æ ¼åå·ãæ¹å·æç´¢ **å端页é¢ç¤ºä¾**ï¼ ``` ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â 产ååºååé¢ç¨éæ¥è¯¢ â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â 产ååç±»: [éæ©åç±» â¼] 产ååç§°: [____] è§æ ¼åå·: [____] [æ¥è¯¢] â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â ââââââââââ¬âââââââââ¬âââââââââââ¬âââââââââ¬âââââââââ¬âââââââââ¬âââââââââ â â â产ååç§°âè§æ ¼åå·â æ¹å· âåºåæ°éâ被é¢ç¨éâå¯é¢ç¨éâ æä½ â â â ââââââââââ¼âââââââââ¼âââââââââââ¼âââââââââ¼âââââââââ¼âââââââââ¼ââââââââ⤠â â âèºä¸å â M6 â20260526- â 100 â 10 â 90 â[é¢ç¨] â â â â â âABC001-001â â â â â â â ââââââââââ¼âââââââââ¼âââââââââââ¼âââââââââ¼âââââââââ¼âââââââââ¼ââââââââ⤠â â âèºä¸å â M6 â20260527- â 50 â 0 â 50 â[é¢ç¨] â â â â â âABC001-001â â â â â â â ââââââââââ¼âââââââââ¼âââââââââââ¼âââââââââ¼âââââââââ¼âââââââââ¼ââââââââ⤠â â âæ³æ â 10寸 â NULL â 30 â 5 â 25 â[é¢ç¨] â â â ââââââââââ´âââââââââ´âââââââââââ´âââââââââ´âââââââââ´âââââââââ´âââââââââ â â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ``` --- ## ä¸ãæ¥å£æ±æ»è¡¨ ### 产åé¢ç¨æ¥å£ | æ¥å£åç§° | 请æ±è·¯å¾ | è¯·æ±æ¹å¼ | 说æ | |----------|----------|----------|------| | å页æ¥è¯¢ | /productBorrow/listPage | POST | æ¥è¯¢é¢ç¨è®°å½å表 | | æ¥è¯¢è¯¦æ | /productBorrow/getDetail | POST | æ ¹æ®IDæ¥è¯¢è¯¦æ | | æ°å¢é¢ç¨ | /productBorrow/add | POST | æ°å¢é¢ç¨ï¼èªå¨åºåºï¼ | | ä¿®æ¹é¢ç¨ | /productBorrow/update | POST | ä¿®æ¹é¢ç¨è®°å½ | | å é¤é¢ç¨ | /productBorrow/delete | POST | æ¹éå é¤é¢ç¨è®°å½ | | æ¹éå®¡æ¹ | /productBorrow/approve | POST | æ¹é审æ¹ï¼éè¿/驳åï¼ | ### 产åå½è¿æ¥å£ | æ¥å£åç§° | 请æ±è·¯å¾ | è¯·æ±æ¹å¼ | 说æ | |----------|----------|----------|------| | å页æ¥è¯¢ | /productBorrowReturn/listPage | POST | æ¥è¯¢å½è¿è®°å½å表 | | æé¢ç¨æ¥è¯¢ | /productBorrowReturn/listByBorrowId | POST | æ¥è¯¢æé¢ç¨çå½è¿è®°å½ | | æ°å¢å½è¿ | /productBorrowReturn/add | POST | æ°å¢å½è¿ï¼èªå¨å ¥åºï¼ | ### åºåæ¥è¯¢æ¥å£ | æ¥å£åç§° | 请æ±è·¯å¾ | è¯·æ±æ¹å¼ | 说æ | |----------|----------|----------|------| | åºååé¢ç¨é | /stockInventory/pageStockAndBorrow | POST | æ¥è¯¢åºåå被é¢ç¨é | --- ## åãç¶æè¯´æ ### 1. 审æ¹ç¶æ (approvalStatus) | å¼ | åç§° | 说æ | |----|------|------| | 0 | å¾ å®¡æ¹ | æ°å¢åçé»è®¤ç¶æï¼ä» æ¹é审æ¹åºæ¯ä½¿ç¨ï¼ | | 1 | å·²éè¿ | 审æ¹éè¿ï¼å·²æ£ååºåï¼å¯è¿è¡å½è¿æä½ | | 2 | 已驳å | å®¡æ¹æªéè¿ï¼ä¸æ£ååºå | **注æ**ï¼æ°å¢é¢ç¨æ¶ç´æ¥èªå¨å®¡æ¹éè¿ï¼ç¶æä¸º1 ### 2. å½è¿ç¶æ (status) | å¼ | åç§° | 说æ | |----|------|------| | 0 | æªå½è¿ | å°æªå½è¿ä»»ä½æ°é | | 1 | é¨åå½è¿ | å·²å½è¿é¨åæ°é | | 2 | å·²å ¨é¨å½è¿ | å·²å½è¿å ¨é¨æ°éï¼ä¸è½åå½è¿ | --- ## äºãä¸å¡æµç¨å¾ ``` âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â é¢ç¨æµç¨ï¼èªå¨åºåºï¼ â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â ââââââââââââââ ââââââââââââââ ââââââââââââââ â â â æ°å¢é¢ç¨ ââââ>â èªå¨åºåº ââââ>â ç¶æè®¾ä¸º â â â â è®°å½ â â æ£ååºå â â å·²éè¿ â â â ââââââââââââââ ââââââââââââââ ââââââââââââââ â â â â â â¼ â â ââââââââââââââ â â â å建åºåº â â â â è®°å½ â â â ââââââââââââââ â â â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â å½è¿æµç¨ï¼èªå¨å ¥åºï¼ â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â ââââââââââââââ ââââââââââââââ ââââââââââââââ â â â éæ©é¢ç¨ ââââ>â å¡«åå½è¿ ââââ>â èªå¨å ¥åº â â â â è®°å½ â â ä¿¡æ¯ â â å¢å åºå â â â ââââââââââââââ ââââââââââââââ ââââââââââââââ â â â â â â¼ â â ââââââââââââââ â â â æ´æ°é¢ç¨ â â â â ç¶æ â â â ââââââââââââââ â â â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ``` --- ## å ãæ³¨æäºé¡¹ ### 1. æ°æ®æ ¡éª **åç«¯æ ¡éª**ï¼ - é¢ç¨æ°éå¿ é¡»å¤§äº0 - å½è¿æ°éä¸è½è¶ è¿å©ä½å¯å½è¿æ°é - é¢ç¨äººãå½è¿äººå¿ é¡»éæ©ç³»ç»ç¨æ· **åç«¯æ ¡éª**ï¼ - é¢ç¨æ¶æ£æ¥åºåæ¯å¦å è¶³ - å½è¿æ°éä¸è½è¶ è¿å©ä½æ°é - å·²å ¨é¨å½è¿çè®°å½ä¸è½åå½è¿ ### 2. ç¨æ·éæ© é¢ç¨äººåå½è¿äººéè¦ä»ç³»ç»ç¨æ·è¡¨éæ©ï¼è°ç¨ç³»ç»ç¨æ·æ¥å£ï¼ ``` POST /system/user/list ``` ### 3. 产åè§æ ¼éæ© éæ©äº§åè§æ ¼æ¶ï¼å¯ä»¥è°ç¨äº§åæ¥å£ï¼ ``` POST /basic/product/pageModel ``` ### 4. åºåèå¨ - **é¢ç¨**ï¼æ°å¢æ¶èªå¨åºåºï¼è°ç¨åºåæ£åæ¥å£ï¼ - **å½è¿**ï¼æ°å¢æ¶èªå¨å ¥åºï¼è°ç¨åºåå¢å æ¥å£ï¼ --- ## ä¸ãé误ç 说æ | éè¯¯ä¿¡æ¯ | åå | è§£å³æ¹æ¡ | |----------|------|----------| | é¢ç¨è®°å½ä¸åå¨ | IDæ æ | æ£æ¥è®°å½ID | | 产ååºåä¸åå¨ | åºå为空 | æ£æ¥åºåæ°æ® | | åºåä¸è¶³æ æ³åºåº | åºåä¸è¶³ | æ£æ¥åºåæ°é | | 该é¢ç¨è®°å½å·²å ¨é¨å½è¿ | å½è¿å®æ | æ é忬¡å½è¿ | | å½è¿æ°éä¸è½å¤§äºå©ä½å¯å½è¿æ°é | æ°éè¶ é | æ£æ¥å©ä½å¯å½è¿æ°é | --- ## å «ãæµè¯ç¨ä¾ ### 1. æ°å¢é¢ç¨ï¼èªå¨åºåºï¼ ```json POST /productBorrow/add { "productModelId": 1, "borrowQuantity": 10, "borrowerId": 1, "borrowerName": "管çå" } ``` ### 2. æ¥è¯¢åºååé¢ç¨é ```json POST /stockInventory/pageStockAndBorrow { "current": 1, "size": 10, "topParentProductId": 277 } ``` ### 3. å½è¿äº§åï¼èªå¨å ¥åºï¼ ```json POST /productBorrowReturn/add { "borrowId": 1, "returnQuantity": 5, "returnerId": 1, "returnerName": "管çå" } ``` ### 4. æ¥è¯¢é¢ç¨è¯¦æ ```json POST /productBorrow/getDetail { "id": 1 } ``` ### 5. æ¥è¯¢å½è¿è®°å½ ```json POST /productBorrowReturn/listByBorrowId { "borrowId": 1, "current": 1, "size": 10 } ``` src/api/inventoryManagement/productBorrow.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,86 @@ import request from "@/utils/request"; // ========== é¢ç¨ç¸å ³æ¥å£ ========== // å页æ¥è¯¢é¢ç¨è®°å½ export const getBorrowListPage = (params) => { return request({ url: "/productBorrow/listPage", method: "post", data: params, }); }; // æ¥è¯¢é¢ç¨è®°å½è¯¦æ export const getBorrowDetail = (params) => { return request({ url: "/productBorrow/getDetail", method: "post", data: params, }); }; // æ°å¢é¢ç¨è®°å½ export const addBorrow = (params) => { return request({ url: "/productBorrow/add", method: "post", data: params, }); }; // ä¿®æ¹é¢ç¨è®°å½ export const updateBorrow = (params) => { return request({ url: "/productBorrow/update", method: "post", data: params, }); }; // å é¤é¢ç¨è®°å½ export const deleteBorrow = (ids) => { return request({ url: "/productBorrow/delete", method: "post", data: ids, }); }; // æ¹é审æ¹é¢ç¨è®°å½ export const approveBorrow = (params) => { return request({ url: "/productBorrow/approve", method: "post", data: params, }); }; // ========== å½è¿ç¸å ³æ¥å£ ========== // å页æ¥è¯¢å½è¿è®°å½ export const getReturnListPage = (params) => { return request({ url: "/productBorrowReturn/listPage", method: "post", data: params, }); }; // æ¥è¯¢æä¸ªé¢ç¨è®°å½çå½è¿è®°å½ export const getReturnListByBorrowId = (params) => { return request({ url: "/productBorrowReturn/listByBorrowId", method: "post", data: params, }); }; // æ°å¢å½è¿è®°å½ export const addReturn = (params) => { return request({ url: "/productBorrowReturn/add", method: "post", data: params, }); }; src/api/inventoryManagement/stockInventory.js
@@ -103,3 +103,12 @@ }); }; // å页æ¥è¯¢äº§ååºååé¢ç¨é export const pageStockAndBorrow = (params) => { return request({ url: "/stockInventory/pageStockAndBorrow", method: "post", data: params, }); }; src/views/basicData/product/index.vue
@@ -9,8 +9,7 @@ @clear="searchFilter" clearable prefix-icon="Search" /> <el-button v-if="false" type="primary" <el-button type="primary" @click="openProDia('addOne')" style="margin-left: 10px">æ°å¢äº§å大类</el-button> </div> src/views/inventoryManagement/stockManagement/OfficeRecord.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,631 @@ <template> <div> <!-- æç´¢è¡¨å --> <div class="search_form mb10"> <el-form ref="searchFormRef" :model="searchForm" class="demo-form-inline"> <el-row :gutter="20"> <el-col :span="4"> <el-form-item label="é¢ç¨åå·" prop="borrowNo"> <el-input v-model="searchForm.borrowNo" style="width: 200px" placeholder="请è¾å ¥" clearable /> </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="产å大类" prop="productName"> <el-input v-model="searchForm.productName" style="width: 200px" placeholder="请è¾å ¥" clearable /> </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="è§æ ¼åå·" prop="model"> <el-input v-model="searchForm.model" style="width: 200px" placeholder="请è¾å ¥" clearable /> </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="é¢ç¨äºº" prop="borrowerName"> <el-input v-model="searchForm.borrowerName" style="width: 200px" placeholder="请è¾å ¥" clearable /> </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="å½è¿ç¶æ" prop="status"> <el-select v-model="searchForm.status" style="width: 200px" placeholder="è¯·éæ©" clearable> <el-option label="æªå½è¿" :value="0" /> <el-option label="é¨åå½è¿" :value="1" /> <el-option label="å·²å ¨é¨å½è¿" :value="2" /> </el-select> </el-form-item> </el-col> <el-col :span="4"> <el-form-item> <el-button type="primary" @click="handleQuery">æç´¢</el-button> <el-button @click="resetSearch">éç½®</el-button> </el-form-item> </el-col> </el-row> </el-form> <div class="flex justify-end mt10"> <el-button type="info" @click="showStockDrawer = true">æ¥è¯¢åºå</el-button> <el-button type="primary" @click="handleAdd">æ°å¢é¢ç¨</el-button> <el-button type="primary" @click="isShowNewModal = true">æ°å¢åºå</el-button> </div> </div> <!-- å表 --> <div class="table_list"> <el-table :data="tableData" border v-loading="tableLoading" style="width: 100%" height="calc(100vh - 18.5em)"> <el-table-column align="center" type="index" label="åºå·" width="60" /> <el-table-column label="é¢ç¨åå·" prop="borrowNo" show-overflow-tooltip width="160" /> <el-table-column label="产ååç§°" prop="productName" show-overflow-tooltip /> <el-table-column label="è§æ ¼åå·" prop="model" show-overflow-tooltip /> <el-table-column label="产åç¼ç " prop="productCode" show-overflow-tooltip /> <el-table-column label="åä½" prop="unit" show-overflow-tooltip width="60" /> <el-table-column label="æ¹å·" prop="batchNo" show-overflow-tooltip /> <el-table-column label="é¢ç¨æ°é" prop="borrowQuantity" show-overflow-tooltip width="100" /> <el-table-column label="å·²å½è¿æ°é" prop="returnedQuantity" show-overflow-tooltip width="100" /> <el-table-column label="å©ä½å¯å½è¿" show-overflow-tooltip width="100"> <template #default="{ row }"> {{ formatQuantity(row.borrowQuantity - row.returnedQuantity) }} </template> </el-table-column> <el-table-column label="é¢ç¨äºº" prop="borrowerName" show-overflow-tooltip width="80" /> <el-table-column label="é¢ç¨æ¶é´" prop="borrowTime" show-overflow-tooltip width="160" /> <el-table-column label="é¢è®¡å½è¿æ¶é´" prop="expectedReturnTime" show-overflow-tooltip width="160" /> <!-- <el-table-column label="审æ¹ç¶æ" prop="approvalStatusName" show-overflow-tooltip width="90">--> <!-- <template #default="{ row }">--> <!-- <el-tag :type="getApprovalStatusType(row.approvalStatus)">{{ row.approvalStatusName }}</el-tag>--> <!-- </template>--> <!-- </el-table-column>--> <el-table-column label="å½è¿ç¶æ" prop="statusName" show-overflow-tooltip width="90"> <template #default="{ row }"> <el-tag :type="getStatusType(row.status)">{{ row.statusName }}</el-tag> </template> </el-table-column> <el-table-column label="夿³¨" prop="remark" show-overflow-tooltip /> <el-table-column fixed="right" label="æä½" min-width="120" align="center"> <template #default="scope"> <el-button link type="primary" @click="handleDetail(scope.row)">详æ </el-button> <el-button v-if="scope.row.status !== 2" link type="success" @click="handleReturn(scope.row)">å½è¿</el-button> </template> </el-table-column> </el-table> <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" :page="page.current" :limit="page.size" @pagination="paginationChange" /> </div> <!-- æ°å¢/ä¿®æ¹é¢ç¨å¼¹çª --> <el-dialog v-model="borrowDialogVisible" :title="borrowDialogTitle" width="600px" destroy-on-close> <el-form ref="borrowFormRef" :model="borrowForm" :rules="borrowRules" label-width="100px"> <el-form-item label="产ååç§°" prop="productModelId"> <el-button type="primary" @click="showProductSelectDialog = true"> {{ borrowForm.productName ? borrowForm.productName : 'éæ©äº§å' }} </el-button> </el-form-item> <el-form-item label="è§æ ¼åå·"> <el-input v-model="borrowForm.model" disabled /> </el-form-item> <el-form-item label="åä½"> <el-input v-model="borrowForm.unit" disabled /> </el-form-item> <el-form-item label="æ¹å·" prop="batchNo"> <el-select v-model="borrowForm.batchNo" filterable placeholder="è¯·éæ©æ¹å·ï¼å¯éï¼" style="width: 100%" clearable> <el-option v-for="item in batchNoList" :key="item" :label="item" :value="item" /> </el-select> </el-form-item> <el-form-item label="é¢ç¨æ°é" prop="borrowQuantity"> <el-input-number v-model="borrowForm.borrowQuantity" :min="0.0001" :precision="4" placeholder="请è¾å ¥é¢ç¨æ°é" style="width: 100%" /> </el-form-item> <el-form-item label="é¢ç¨äºº" prop="borrowerId"> <el-select v-model="borrowForm.borrowerId" filterable placeholder="è¯·éæ©é¢ç¨äºº" style="width: 100%" @change="handleBorrowerChange"> <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> </el-select> </el-form-item> <el-form-item label="é¢è®¡å½è¿æ¶é´" prop="expectedReturnTime"> <el-date-picker v-model="borrowForm.expectedReturnTime" type="datetime" placeholder="è¯·éæ©é¢è®¡å½è¿æ¶é´" style="width: 100%" value-format="YYYY-MM-DD HH:mm:ss" /> </el-form-item> <el-form-item label="夿³¨" prop="remark"> <el-input v-model="borrowForm.remark" type="textarea" :rows="3" placeholder="请è¾å ¥å¤æ³¨" /> </el-form-item> </el-form> <!-- 产åéæ©å¼¹çª --> <ProductSelectDialog v-model="showProductSelectDialog" @confirm="handleProductSelect" :top-product-parent-id="props.productId" single /> <template #footer> <el-button @click="borrowDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="submitBorrowForm">ç¡®å®</el-button> </template> </el-dialog> <!-- å½è¿å¼¹çª --> <el-dialog v-model="returnDialogVisible" title="产åå½è¿" width="500px" destroy-on-close> <el-form ref="returnFormRef" :model="returnForm" :rules="returnRules" label-width="100px"> <el-form-item label="é¢ç¨åå·"> <el-input v-model="currentBorrow.borrowNo" disabled /> </el-form-item> <el-form-item label="产åä¿¡æ¯"> <el-input :value="`${currentBorrow.productName} - ${currentBorrow.model}`" disabled /> </el-form-item> <el-form-item label="é¢ç¨æ°é"> <el-input :value="currentBorrow.borrowQuantity" disabled /> </el-form-item> <el-form-item label="å·²å½è¿æ°é"> <el-input :value="currentBorrow.returnedQuantity" disabled /> </el-form-item> <el-form-item label="å©ä½å¯å½è¿"> <el-input :value="formatQuantity(currentBorrow.borrowQuantity - currentBorrow.returnedQuantity)" disabled /> </el-form-item> <el-form-item label="å½è¿æ°é" prop="returnQuantity"> <el-input-number v-model="returnForm.returnQuantity" :min="0.0001" :max="currentBorrow.borrowQuantity - currentBorrow.returnedQuantity" :precision="4" placeholder="请è¾å ¥å½è¿æ°é" style="width: 100%" /> </el-form-item> <el-form-item label="å½è¿äºº" prop="returnerId"> <el-select v-model="returnForm.returnerId" filterable placeholder="è¯·éæ©å½è¿äºº" style="width: 100%" @change="handleReturnerChange"> <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> </el-select> </el-form-item> <el-form-item label="夿³¨" prop="remark"> <el-input v-model="returnForm.remark" type="textarea" :rows="3" placeholder="请è¾å ¥å¤æ³¨" /> </el-form-item> </el-form> <template #footer> <el-button @click="returnDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="submitReturnForm">ç¡®å®</el-button> </template> </el-dialog> <!-- 详æ å¼¹çª --> <el-dialog v-model="detailDialogVisible" title="é¢ç¨è¯¦æ " width="700px" destroy-on-close> <el-descriptions :column="2" border> <el-descriptions-item label="é¢ç¨åå·">{{ detailData.borrowNo }}</el-descriptions-item> <el-descriptions-item label="产ååç§°">{{ detailData.productName }}</el-descriptions-item> <el-descriptions-item label="è§æ ¼åå·">{{ detailData.model }}</el-descriptions-item> <el-descriptions-item label="产åç¼ç ">{{ detailData.productCode }}</el-descriptions-item> <el-descriptions-item label="åä½">{{ detailData.unit }}</el-descriptions-item> <el-descriptions-item label="æ¹å·">{{ detailData.batchNo }}</el-descriptions-item> <el-descriptions-item label="é¢ç¨æ°é">{{ detailData.borrowQuantity }}</el-descriptions-item> <el-descriptions-item label="å·²å½è¿æ°é">{{ detailData.returnedQuantity }}</el-descriptions-item> <el-descriptions-item label="å©ä½å¯å½è¿">{{ formatQuantity(detailData.borrowQuantity - detailData.returnedQuantity) }}</el-descriptions-item> <el-descriptions-item label="é¢ç¨äºº">{{ detailData.borrowerName }}</el-descriptions-item> <el-descriptions-item label="é¢ç¨æ¶é´">{{ detailData.borrowTime }}</el-descriptions-item> <el-descriptions-item label="é¢è®¡å½è¿æ¶é´">{{ detailData.expectedReturnTime }}</el-descriptions-item> <el-descriptions-item label="审æ¹ç¶æ"> <el-tag :type="getApprovalStatusType(detailData.approvalStatus)">{{ detailData.approvalStatusName }}</el-tag> </el-descriptions-item> <el-descriptions-item label="å½è¿ç¶æ"> <el-tag :type="getStatusType(detailData.status)">{{ detailData.statusName }}</el-tag> </el-descriptions-item> <el-descriptions-item label="夿³¨" :span="2">{{ detailData.remark }}</el-descriptions-item> <el-descriptions-item label="å建æ¶é´" :span="2">{{ detailData.createTime }}</el-descriptions-item> </el-descriptions> <!-- å½è¿è®°å½ --> <div v-if="detailData.approvalStatus === 1" class="mt20"> <div class="mb10 fw-bold">å½è¿è®°å½</div> <el-table :data="returnRecordList" border style="width: 100%" max-height="200"> <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column label="å½è¿æ°é" prop="returnQuantity" /> <el-table-column label="å½è¿äºº" prop="returnerName" /> <el-table-column label="å½è¿æ¶é´" prop="returnTime" /> <el-table-column label="夿³¨" prop="remark" /> </el-table> </div> </el-dialog> <!-- æ°å¢åºåå¼¹çª --> <NewStockInventory v-if="isShowNewModal" v-model:visible="isShowNewModal" :top-product-parent-id="props.productId" @completed="getList" /> <!-- åºåæ¥è¯¢ä¾§è¾¹æ --> <el-drawer v-model="showStockDrawer" title="åºååé¢ç¨éæ¥è¯¢" size="1000px" direction="rtl" destroy-on-close @open="handleStockDrawerOpen"> <div class="stock-drawer-content"> <!-- æç´¢è¡¨å --> <el-form :inline="true" class="mb10"> <el-form-item label="产ååç§°"> <el-input v-model="stockSearchForm.productName" placeholder="请è¾å ¥" clearable style="width: 150px" /> </el-form-item> <el-form-item label="è§æ ¼åå·"> <el-input v-model="stockSearchForm.model" placeholder="请è¾å ¥" clearable style="width: 150px" /> </el-form-item> <el-form-item label="æ¹å·"> <el-input v-model="stockSearchForm.batchNo" placeholder="请è¾å ¥" clearable style="width: 150px" /> </el-form-item> <el-form-item> <el-button type="primary" @click="getStockList">æ¥è¯¢</el-button> <el-button @click="resetStockSearch">éç½®</el-button> </el-form-item> </el-form> <!-- åºåå表 --> <el-table :data="stockTableData" border v-loading="stockTableLoading" style="width: 100%" height="calc(100vh - 200px)"> <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column label="产ååç§°" prop="productName" show-overflow-tooltip /> <el-table-column label="è§æ ¼åå·" prop="model" show-overflow-tooltip /> <el-table-column label="æ¹å·" prop="batchNo" show-overflow-tooltip> <template #default="{ row }"> {{ row.batchNo || '-' }} </template> </el-table-column> <el-table-column label="åºåæ°é" prop="qualitity" show-overflow-tooltip width="100" /> <el-table-column label="被é¢ç¨é" prop="borrowedQuantity" show-overflow-tooltip width="90" /> <el-table-column label="å¯é¢ç¨é" prop="availableQuantity" show-overflow-tooltip width="90"> <template #default="{ row }"> <span :class="{ 'text-danger': row.availableQuantity <= 0 }">{{ formatQuantity(row.availableQuantity) }}</span> </template> </el-table-column> <el-table-column label="åä½" prop="unit" show-overflow-tooltip width="60" /> </el-table> <pagination v-show="stockTotal > 0" :total="stockTotal" layout="total, sizes, prev, pager, next, jumper" :page="stockPage.current" :limit="stockPage.size" @pagination="stockPaginationChange" /> </div> </el-drawer> </div> </template> <script setup> import pagination from "@/components/PIMTable/Pagination.vue"; import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; import NewStockInventory from "@/views/inventoryManagement/stockManagement/New.vue"; import { ref, reactive, toRefs, onMounted, getCurrentInstance, defineAsyncComponent } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; import { getBorrowListPage, getBorrowDetail, addBorrow, getReturnListByBorrowId, addReturn, } from "@/api/inventoryManagement/productBorrow.js"; import { pageStockAndBorrow } from "@/api/inventoryManagement/stockInventory.js"; import { userListNoPage } from "@/api/system/user.js"; const props = defineProps({ productId: { type: Number, required: true, default: 0, }, }); const { proxy } = getCurrentInstance(); // è¡¨æ ¼æ°æ® const tableData = ref([]); const tableLoading = ref(false); const page = reactive({ current: 1, size: 100, }); const total = ref(0); // æç´¢è¡¨å const data = reactive({ searchForm: { borrowNo: "", productName: "", model: "", borrowerName: "", status: null, }, }); const { searchForm } = toRefs(data); const searchFormRef = ref(null); // ç¨æ·å表 const userList = ref([]); // 产åéæ©å¼¹çª const showProductSelectDialog = ref(false); // æ¹å·å表 const batchNoList = ref([]); // é¢ç¨å¼¹çª const borrowDialogVisible = ref(false); const borrowDialogTitle = ref("æ°å¢é¢ç¨"); const borrowFormRef = ref(null); const borrowForm = ref({ id: null, productModelId: null, productName: "", model: "", unit: "", batchNo: "", borrowQuantity: null, borrowerId: null, borrowerName: "", expectedReturnTime: "", remark: "", }); const borrowRules = { productModelId: [{ required: true, message: "è¯·éæ©äº§å", trigger: "change" }], borrowQuantity: [{ required: true, message: "请è¾å ¥é¢ç¨æ°é", trigger: "blur" }], borrowerId: [{ required: true, message: "è¯·éæ©é¢ç¨äºº", trigger: "change" }], }; // å½è¿å¼¹çª const returnDialogVisible = ref(false); const returnFormRef = ref(null); const returnForm = ref({ borrowId: null, returnQuantity: null, returnerId: null, returnerName: "", remark: "", }); const returnRules = { returnQuantity: [{ required: true, message: "请è¾å ¥å½è¿æ°é", trigger: "blur" }], returnerId: [{ required: true, message: "è¯·éæ©å½è¿äºº", trigger: "change" }], }; const currentBorrow = ref({}); // 详æ å¼¹çª const detailDialogVisible = ref(false); const detailData = ref({}); const returnRecordList = ref([]); // æ°å¢åºåå¼¹çª const isShowNewModal = ref(false); // åºåæ¥è¯¢ä¾§è¾¹æ const showStockDrawer = ref(false); const stockTableData = ref([]); const stockTableLoading = ref(false); const stockPage = reactive({ current: 1, size: 10, }); const stockTotal = ref(0); const stockSearchForm = reactive({ productName: "", model: "", batchNo: "", }); // è·åç¨æ·å表 const getUserList = async () => { try { const res = await userListNoPage(); userList.value = res.data || []; } catch (error) { console.error("è·åç¨æ·å表失败", error); } }; // æ¥è¯¢å表 const getList = async () => { tableLoading.value = true; try { const res = await getBorrowListPage({ ...searchForm.value, ...page }); tableData.value = res.data?.records || []; total.value = res.data?.total || 0; } catch (error) { console.error("æ¥è¯¢å表失败", error); } finally { tableLoading.value = false; } }; const handleQuery = () => { page.current = 1; getList(); }; const resetSearch = () => { searchFormRef.value?.resetFields(); page.current = 1; getList(); }; const paginationChange = (obj) => { page.current = obj.page; page.size = obj.limit; getList(); }; // ç¶ææ ç¾ç±»å const getApprovalStatusType = (status) => { const map = { 0: "warning", 1: "success", 2: "danger" }; return map[status] || ""; }; const getStatusType = (status) => { const map = { 0: "danger", 1: "warning", 2: "success" }; return map[status] || ""; }; // æ ¼å¼åæ°éï¼å»æå°¾é¨å¤ä½ç0 const formatQuantity = (num) => { if (num == null) return ""; const fixed = Number(num).toFixed(4); return parseFloat(fixed).toString(); }; // æ°å¢é¢ç¨ const handleAdd = () => { borrowDialogTitle.value = "æ°å¢é¢ç¨"; borrowForm.value = { id: null, productModelId: null, productName: "", model: "", unit: "", batchNo: "", borrowQuantity: null, borrowerId: null, borrowerName: "", expectedReturnTime: "", remark: "", }; batchNoList.value = []; borrowDialogVisible.value = true; }; // 产åéæ©å¤ç const handleProductSelect = (products) => { if (products && products.length > 0) { const product = products[0]; borrowForm.value.productModelId = product.id; borrowForm.value.productName = product.productName; borrowForm.value.model = product.model; borrowForm.value.unit = product.unit; borrowForm.value.batchNo = ""; // éç½®æ¹å·éæ© batchNoList.value = product.batchNoList || []; // ä»äº§åæ°æ®å¸¦åºæ¹å·å表 showProductSelectDialog.value = false; // 触å表åéªè¯æ´æ° borrowFormRef.value?.validateField("productModelId"); } }; // é¢ç¨äººåæ´ const handleBorrowerChange = (val) => { const user = userList.value.find((item) => item.userId === val); borrowForm.value.borrowerName = user?.nickName || ""; }; // æäº¤é¢ç¨è¡¨å const submitBorrowForm = async () => { await borrowFormRef.value?.validate(); try { await addBorrow(borrowForm.value); ElMessage.success("æ°å¢æå"); borrowDialogVisible.value = false; getList(); } catch (error) { console.error("æäº¤å¤±è´¥", error); } }; // å½è¿ const handleReturn = (row) => { currentBorrow.value = row; returnForm.value = { borrowId: row.id, returnQuantity: null, returnerId: null, returnerName: "", remark: "", }; returnDialogVisible.value = true; }; // å½è¿äººåæ´ const handleReturnerChange = (val) => { const user = userList.value.find((item) => item.userId === val); returnForm.value.returnerName = user?.nickName || ""; }; // æäº¤å½è¿è¡¨å const submitReturnForm = async () => { await returnFormRef.value?.validate(); try { await addReturn(returnForm.value); ElMessage.success("å½è¿æå"); returnDialogVisible.value = false; getList(); } catch (error) { console.error("å½è¿å¤±è´¥", error); } }; // æ¥ç详æ const handleDetail = async (row) => { try { const res = await getBorrowDetail({ id: row.id }); detailData.value = res.data || {}; // 妿已éè¿ï¼æ¥è¯¢å½è¿è®°å½ if (detailData.value.approvalStatus === 1) { const returnRes = await getReturnListByBorrowId({ borrowId: row.id, current: 1, size: 100 }); returnRecordList.value = returnRes.data?.records || []; } else { returnRecordList.value = []; } detailDialogVisible.value = true; } catch (error) { console.error("è·å详æ 失败", error); } }; // æ¥è¯¢åºåå表 const getStockList = async () => { stockTableLoading.value = true; try { const res = await pageStockAndBorrow({ ...stockSearchForm, ...stockPage, topParentProductId: props.productId, }); stockTableData.value = res.data?.records || []; stockTotal.value = res.data?.total || 0; } catch (error) { console.error("æ¥è¯¢åºå失败", error); } finally { stockTableLoading.value = false; } }; // éç½®åºåæç´¢ const resetStockSearch = () => { stockSearchForm.productName = ""; stockSearchForm.model = ""; stockSearchForm.batchNo = ""; stockPage.current = 1; getStockList(); }; // åºåå页åå const stockPaginationChange = (obj) => { stockPage.current = obj.page; stockPage.size = obj.limit; getStockList(); }; // çå¬åºåä¾§è¾¹æ æå¼ï¼èªå¨å è½½æ°æ® const handleStockDrawerOpen = () => { stockPage.current = 1; getStockList(); }; onMounted(() => { getUserList(); getList(); }); </script> <style scoped lang="scss"> .mt10 { margin-top: 10px; } .mt20 { margin-top: 20px; } .mb10 { margin-bottom: 10px; } .fw-bold { font-weight: bold; } .stock-drawer-content { padding: 0 20px; } .text-danger { color: #f56c6c; } .flex { display: flex; } .justify-end { justify-content: flex-end; } </style> src/views/inventoryManagement/stockManagement/index.vue
@@ -6,7 +6,8 @@ :label="tab.productName" :name="tab.id" :key="tab.id"> <Record :product-id="tab.id" v-if="tab.id === activeTab" /> <OfficeRecord :product-id="tab.id" v-if="tab.id === activeTab && tab.productName === 'åå ¬ç¨å'" /> <Record :product-id="tab.id" v-else-if="tab.id === activeTab" /> </el-tab-pane> </el-tabs> </div> @@ -17,6 +18,7 @@ import { ref, onMounted } from 'vue'; import { productTreeList } from "@/api/basicData/product.js"; import Record from "@/views/inventoryManagement/stockManagement/Record.vue"; import OfficeRecord from "@/views/inventoryManagement/stockManagement/OfficeRecord.vue"; const products = ref([]) const activeTab = ref(null) const loading = ref(false) @@ -41,4 +43,4 @@ onMounted(() => { fetchProducts(); }) </script> </script>