docs/ProductionOperationTaskǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,200 @@ # ProductionOperationTask å端èè°ææ¡£ ## ä¸ãåæ´æ¦è¿° `ProductionOperationTaskController` 模ååäºä»¥ä¸è°æ´ï¼ 1. `/page` å页æ¥å£æ¹ä¸º**æç产订åå·åç»**ï¼å·¥åºèåè¿å 2. æ¥è¯¢æ¡ä»¶ç®åä¸ºä» æ¯æ `npsNo`ï¼è®¢åå·æ¨¡ç³æç´¢ï¼ 3. æ°å¢ `/byOrder/{orderId}` æ¥å£ï¼æ ¹æ®ç产订å ID æ¥è¯¢ï¼**ç´æ¥å¤ç¨äº `list` æ¹æ³** ## äºãlist å¤ç¨è¯´æ **ä¸è½ç´æ¥å¤ç¨åæ¥ç `list`**ã忥ç `list` åªæ¥ `production_operation_task` åè¡¨ï¼æ²¡æ JOIN å ³è表ï¼ç¼ºå° `productName`ã`model`ã`unit`ã`operationName` çåæ®µãå·²å° `list` æ¹ä¸ºè°ç¨ä¸ `page` ç¸åçåç»æ¥è¯¢ SQLï¼ä» 廿äºå页å 裹ï¼ï¼ç°å¨ `/list` å `/byOrder/{orderId}` å ±ç¨åä¸å¥æ¥è¯¢é»è¾ã --- ## ä¸ãæ¥å£è¯¦æ ### 1. å页æ¥è¯¢ï¼å·²æ¹é ï¼ ``` GET /productionOperationTask/page ``` **请æ±åæ°ï¼** | åæ° | ç±»å | å¿ å¡« | 说æ | |------|------|------|------| | current | int | å¦ | å½å页ï¼é»è®¤ 1 | | size | int | å¦ | æ¯é¡µæ¡æ°ï¼é»è®¤ 10 | | npsNo | string | å¦ | 订åå·ï¼æ¨¡ç³æç´¢ | > 注æï¼åæç `id`ã`productionOrderId`ã`productionOrderRoutingOperationId`ã`status`ã`isProduction`ã`workOrderNo` æ¥è¯¢æ¡ä»¶å·²ç§»é¤ï¼ä¸åçæã **请æ±ç¤ºä¾ï¼** ``` GET /productionOperationTask/page?current=1&size=10&npsNo=NPS2026 ``` **ååºç»æï¼** ```json { "code": 200, "data": { "records": [ { "productionOrderId": 1001, "npsNo": "NPS202606001", "endOrder": false, "productName": "ææäº§å", "model": "XL-2026", "unit": "个", "operationName": "åå²,çæ¥,æç£¨", "productionTaskCount": 3, "planQuantity": 100, "completeQuantity": 80, "goodQuantity": 80, "scrapQty": 5, "completionStatus": 80.00, "type": 1, "workOrderType": "æ£å¸¸", "workOrderNo": "WO202606001,WO202606002,WO202606003", "planStartTime": "2026-06-01", "planEndTime": "2026-06-15", "actualStartTime": "2026-06-02", "actualEndTime": "2026-06-14", "status": 4, "userNames": "å¼ ä¸,æå" } ], "total": 50, "current": 1, "size": 10 } } ``` --- ### 2. æ ¹æ®ç产订åIDæ¥è¯¢ï¼æ°å¢ï¼ ``` GET /productionOperationTask/byOrder/{orderId} ``` **è·¯å¾åæ°ï¼** | åæ° | ç±»å | å¿ å¡« | 说æ | |------|------|------|------| | orderId | Long | æ¯ | ç产订å IDï¼production_order 表主é®ï¼ | **请æ±ç¤ºä¾ï¼** ``` GET /productionOperationTask/byOrder/1001 ``` **ååºç»æï¼** ä¸ `/page` ç `records` å项ä¸è´ï¼å¤å±ä¸ºæ°ç»ï¼é常 0-1 æ¡ï¼ã ```json { "code": 200, "data": [ { "productionOrderId": 1001, "npsNo": "NPS202606001", "endOrder": false, "productName": "ææäº§å", "model": "XL-2026", "unit": "个", "operationName": "åå²,çæ¥,æç£¨", "productionTaskCount": 3, "planQuantity": 100, "completeQuantity": 80, "goodQuantity": 80, "scrapQty": 5, "completionStatus": 80.00, "type": 1, "workOrderType": "æ£å¸¸", "workOrderNo": "WO202606001,WO202606002,WO202606003", "planStartTime": "2026-06-01", "planEndTime": "2026-06-15", "actualStartTime": "2026-06-02", "actualEndTime": "2026-06-14", "status": 4, "userNames": "å¼ ä¸,æå" } ] } ``` --- ### 3. å·¥åå表ï¼åæ¥æ¹é ï¼ ``` GET /productionOperationTask/list ``` **请æ±åæ°ï¼** | åæ° | ç±»å | å¿ å¡« | 说æ | |------|------|------|------| | npsNo | string | å¦ | 订åå·ï¼æ¨¡ç³æç´¢ | | productionOrderId | Long | å¦ | ç产订å IDï¼ç²¾ç¡®å¹é | **请æ±ç¤ºä¾ï¼** ``` GET /productionOperationTask/list?npsNo=NPS2026 GET /productionOperationTask/list?productionOrderId=1001 ``` **ååºç»æï¼** å `/byOrder/{orderId}`ï¼è¿åæ°ç»ã --- ## åãååºå段说æ | åæ®µ | ç±»å | 说æ | |------|------|------| | productionOrderId | Long | ç产订å ID | | npsNo | string | 订åå· | | endOrder | boolean | æ¯å¦ç»å | | productName | string | 产ååç§° | | model | string | è§æ ¼åå· | | unit | string | åä½ | | operationName | string | å·¥åºåç§°ï¼å¤ä¸ªç¨éå·æ¼æ¥ï¼æ drag_sort æåº | | productionTaskCount | Long | 该订åä¸ççäº§ä»»å¡æ° | | planQuantity | BigDecimal | è®¡åæ°éï¼å任塿±æ»ï¼ | | completeQuantity | BigDecimal | 宿æ°éï¼å任塿±æ»ï¼ | | goodQuantity | BigDecimal | è¯åæ°éï¼çäº completeQuantity æ±æ»ï¼ | | scrapQty | BigDecimal | æ¥åºæ°éï¼å任塿±æ»ï¼ | | completionStatus | BigDecimal | 宿è¿åº¦ç¾åæ¯ï¼å¦ 80.00 | | type | Integer | å·¥åºç±»åï¼0=计æ¶ï¼1=计件 | | workOrderType | string | å·¥åç±»åï¼"æ£å¸¸" / "è¿å·¥è¿ä¿®"ï¼ä»»ä¸ä»»å¡ä¸ºè¿å·¥åæ¾ç¤ºè¿å·¥è¿ä¿®ï¼ | | workOrderNo | string | å·¥åç¼å·ï¼å¤ä¸ªç¨éå·æ¼æ¥ | | planStartTime | LocalDate | ææ©è®¡åå¼å§æ¶é´ | | planEndTime | LocalDate | ææè®¡åç»ææ¶é´ | | actualStartTime | LocalDate | ææ©å®é å¼å§æ¶é´ | | actualEndTime | LocalDate | ææå®é ç»ææ¶é´ | | status | Integer | ç¶æï¼åæå¤§å¼ï¼1=å¾ ç¡®è®¤, 2=å¾ ç产, 3=ç产ä¸, 4=å·²ç产 | | userNames | string | æ¥å·¥äººååç§°ï¼å¤ä¸ªéå·åé | --- ## äºã䏿§æ¥å£çæ ¸å¿å·®å¼ | å·®å¼ç¹ | æ§ page | æ° page | |--------|---------|---------| | æ°æ®ç»æ | æ¯è¡ä¸æ¡ä»»å¡ | æ¯è¡ä¸ä¸ªç产订åï¼ä»»å¡èåï¼ | | operationName | å个工åºå | éå·æ¼æ¥çå·¥åºåå表 | | æ¥è¯¢æ¡ä»¶ | 7 ä¸ªè¿æ»¤å段 | ä» npsNo | | planQuantity | åä»»å¡è®¡åæ° | è¯¥è®¢åææä»»å¡è®¡åæ°æ±æ» | --- ## å ãå端èè°è¦ç¹ 1. `/page` 忥æ¯è¡ä¸ä¸ªå·¥åºä»»å¡ï¼ç°å¨æ¯æ¯è¡ä¸ä¸ªè®¢åï¼è¡¨æ ¼åå®ä¹éè¦ç¸åºè°æ´ 2. 妿éè¦å±ç¤ºè®¢åä¸çå·¥åºæç»ï¼å¯ç»å `/getOperation` æ¥å£ï¼è¯¥æ¥å£æå·¥åºåç»ï¼æ¯æ `productionOrderId` è¿æ»¤ï¼ 3. `/byOrder/{orderId}` è¿åæ°ç»ï¼å第ä¸ä¸ªå ç´ å³å¯ï¼æå¤ç©ºå¤çï¼ 4. `operationName` åæ®µç°å¨å¯è½å å«å¤ä¸ªå·¥åºåï¼éå·æ¼æ¥ï¼ï¼æ³¨æå端å±ç¤ºå¤çï¼å¦æ¢è¡ææ ç¾å±ç¤ºï¼ docs/¸¶¿îÉêÇ븶¿î״̬¹¦ÄÜÎĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,327 @@ # 仿¬¾ç³è¯·"仿¬¾ç¶æ"åè½ææ¡£ ## ä¸ãéæ±èæ¯ 仿¬¾ç³è¯·ï¼AccountPaymentApplicationï¼éè¦æ¯æå¤æ¬¡ä»æ¬¾ï¼æ°å¢ç¬ç«ç"仿¬¾ç¶æ"åæ®µï¼ä¸åæç"å®¡æ ¸ç¶æ"åºåã **åæå®¡æ ¸ç¶æï¼statusï¼**ï¼ - 0ï¼å¾ å®¡æ ¸ - 1ï¼å®¡æ ¸éè¿ - 2ï¼å®¡æ ¸ä¸éè¿ **æ°å¢ä»æ¬¾ç¶æï¼payment_statusï¼**ï¼ - 0ï¼æªä»æ¬¾ - 1ï¼é¨å仿¬¾ - 2ï¼å·²ä»æ¬¾ --- ## äºãæ°æ®åºåæ´ï¼SQLï¼ ```sql -- ===================================================== -- 1. 仿¬¾ç³è¯·è¡¨æ°å¢ä»æ¬¾ç¶æå段 -- ===================================================== ALTER TABLE `account_payment_application` ADD COLUMN `payment_status` INT DEFAULT 0 COMMENT '仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾' AFTER `status`; -- ===================================================== -- 2. åå§åå岿°æ®ç仿¬¾ç¶æ -- ===================================================== -- æ ¹æ®å·²åå¨ç仿¬¾å计ç®ä»æ¬¾ç¶æ UPDATE account_payment_application apa SET apa.payment_status = ( CASE WHEN apa.payment_amount IS NULL OR apa.payment_amount = 0 THEN 0 ELSE ( SELECT CASE WHEN IFNULL(SUM(app.payment_amount), 0) = 0 THEN 0 WHEN IFNULL(SUM(app.payment_amount), 0) < apa.payment_amount THEN 1 ELSE 2 END FROM account_purchase_payment app WHERE app.account_payment_application_id = apa.id ) END ); -- ===================================================== -- 3. åæ®µè¯´æ -- ===================================================== -- account_payment_application 表æ°å¢åæ®µï¼ -- payment_status - 仿¬¾ç¶æï¼æ°å¢ï¼ -- 0 = æªä»æ¬¾ï¼é»è®¤å¼ï¼æ 仿¬¾åæç´¯è®¡ä»æ¬¾éé¢ä¸º0ï¼ -- 1 = é¨å仿¬¾ï¼ç´¯è®¡ä»æ¬¾éé¢ < ç³è¯·éé¢ï¼ -- 2 = 已仿¬¾ï¼ç´¯è®¡ä»æ¬¾éé¢ >= ç³è¯·éé¢ï¼ -- -- åæåæ®µä¿æä¸åï¼ -- status - å®¡æ ¸ç¶æ -- 0 = å¾ å®¡æ ¸ -- 1 = å®¡æ ¸éè¿ -- 2 = å®¡æ ¸ä¸éè¿ ``` --- ## ä¸ãå端æ¹å¨ç¹ ### 3.1 å®ä½ç±»ä¿®æ¹ **AccountPaymentApplication.java** ```java /** * å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸ 1å®¡æ ¸éè¿ 2å®¡æ ¸ä¸éè¿ */ @ApiModelProperty("å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸ 1å®¡æ ¸éè¿ 2å®¡æ ¸ä¸éè¿") @Excel(name = "å®¡æ ¸ç¶æ", readConverterExp = "0=å¾ å®¡æ ¸,1=å®¡æ ¸éè¿,2=å®¡æ ¸ä¸éè¿") private Integer status; /** * 仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾ */ @ApiModelProperty("仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾") @Excel(name = "仿¬¾ç¶æ", readConverterExp = "0=æªä»æ¬¾,1=é¨å仿¬¾,2=已仿¬¾") private Integer paymentStatus; /** * 已仿¬¾éé¢ï¼éæä¹ åï¼æ¥è¯¢æ¶è®¡ç®ï¼ */ @ApiModelProperty("已仿¬¾éé¢") @TableField(exist = false) private BigDecimal paidAmount; ``` ### 3.2 仿¬¾åæ°å¢é»è¾ **æ°å¢ä»æ¬¾åæ¶èªå¨æ´æ°ä»æ¬¾ç¶æï¼** ```java private void updatePaymentStatus(AccountPaymentApplication application, BigDecimal paidAmount) { BigDecimal applyAmount = application.getPaymentAmount(); int newPaymentStatus; if (paidAmount.compareTo(BigDecimal.ZERO) == 0) { newPaymentStatus = 0; // æªä»æ¬¾ } else if (paidAmount.compareTo(applyAmount) < 0) { newPaymentStatus = 1; // é¨å仿¬¾ } else { newPaymentStatus = 2; // 已仿¬¾ } application.setPaymentStatus(newPaymentStatus); accountPaymentApplicationMapper.updateById(application); } ``` ### 3.3 仿¬¾åå é¤é»è¾ **å é¤ä»æ¬¾åæ¶èªå¨æ´æ°ä»æ¬¾ç¶æï¼** å é¤ä»æ¬¾ååï¼éæ°è®¡ç®å©ä½ä»æ¬¾éé¢ï¼æ´æ°ä»æ¬¾ç¶æï¼å¯è½ä»"已仿¬¾"å为"é¨å仿¬¾"æ"æªä»æ¬¾"ï¼ã --- ## åãä¸å¡æµç¨å¾ ``` âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â 仿¬¾ç³è¯·æµç¨ â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â æ°å¢ä»æ¬¾ç³è¯· â â status=0(å¾ å®¡æ ¸), payment_status=0(æªä»æ¬¾) â â â â â â¼ â â âââââââââââââââ â â â å®¡æ ¸æä½ â â â âââââââââââââââ â â â â â ââââââ´âââââ â â éè¿ ä¸éè¿ â â â â â â â¼ â¼ â â status=1 status=2 â â payment_ payment_ â â status=0 status=0 â â (å®¡æ ¸éè¿) (å®¡æ ¸ä¸éè¿) â â â â â â ä¸éè¿ï¼ä¸è½ä»æ¬¾ â â â¼ â â å¯ä»¥æ°å¢ä»æ¬¾å â â â â â â¼ â â æ°å¢ä»æ¬¾å1 â â ç´¯è®¡ä»æ¬¾ < ç³è¯·éé¢ â â payment_status=1(é¨å仿¬¾) â â â â â â¼ â â æ°å¢ä»æ¬¾å2 â â ç´¯è®¡ä»æ¬¾ = ç³è¯·éé¢ â â payment_status=2(已仿¬¾) â â â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ``` --- ## äºãç¶æå¯¹ç §è¡¨ ### 5.1 å®¡æ ¸ç¶æ vs 仿¬¾ç¶æ | å®¡æ ¸ç¶æ(status) | 说æ | 仿¬¾ç¶æ(payment_status) | 说æ | |------------------|------|--------------------------|------| | 0 | å¾ å®¡æ ¸ | 0 | æªä»æ¬¾ | | 1 | å®¡æ ¸éè¿ | 1 | é¨å仿¬¾ | | 2 | å®¡æ ¸ä¸éè¿ | 2 | 已仿¬¾ | **ä¸¤ä¸ªç¶æç¬ç«åå¨ï¼äºä¸å½±åï¼** - å®¡æ ¸éè¿(status=1)åæè½ä»æ¬¾ - 仿¬¾ç¶ææ ¹æ®ç´¯è®¡ä»æ¬¾éé¢èªå¨è®¡ç® ### 5.2 ç¶æç»ååºæ¯ | status | payment_status | åºæ¯è¯´æ | |--------|----------------|----------| | 0 | 0 | æ°å¢ä»æ¬¾ç³è¯·ï¼çå¾ å®¡æ ¸ | | 1 | 0 | å®¡æ ¸éè¿ï¼ä½å°æªä»æ¬¾ | | 1 | 1 | å®¡æ ¸éè¿ï¼å·²é¨å仿¬¾ | | 1 | 2 | å®¡æ ¸éè¿ï¼å·²å ¨é¢ä»æ¬¾ | | 2 | 0 | å®¡æ ¸ä¸éè¿ï¼ä¸è½ä»æ¬¾ | --- ## å ãå端æ¹å¨ç¹ ### 6.1 仿¬¾ç³è¯·åè¡¨é¡µé¢ **æ°å¢åå±ç¤ºï¼** | åæ®µ | åå | 说æ | |------|------|------| | status | å®¡æ ¸ç¶æ | 0å¾ å®¡æ ¸/1å®¡æ ¸éè¿/2å®¡æ ¸ä¸éè¿ | | payment_status | 仿¬¾ç¶æï¼æ°å¢ï¼ | 0æªä»æ¬¾/1é¨å仿¬¾/2已仿¬¾ | | paidAmount | 已仿¬¾éé¢ï¼æ°å¢ï¼ | ç´¯è®¡å·²ä»æ¬¾éé¢ï¼æ¥è¯¢æ¶è®¡ç®ï¼ | | paymentAmount | ç³è¯·éé¢ | 仿¬¾ç³è¯·æ»éé¢ | **ç¶ææ ç¾é¢è²å»ºè®®ï¼** | 仿¬¾ç¶æ | ç¶æåç§° | æ ç¾é¢è² | |----------|----------|----------| | 0 | æªä»æ¬¾ | warningï¼æ©è²ï¼ | | 1 | å仿¬¾ | primaryï¼èè²ï¼ | | 2 | 已仿¬¾ | successï¼ç»¿è²ï¼ | ### 6.2 仿¬¾ç³è¯·å表çé **ç鿡件æ°å¢ï¼** ``` å®¡æ ¸ç¶æï¼å ¨é¨ / å¾ å®¡æ ¸ / å®¡æ ¸éè¿ / å®¡æ ¸ä¸éè¿ ä»æ¬¾ç¶æï¼å ¨é¨ / æªä»æ¬¾ / é¨å仿¬¾ / 已仿¬¾ï¼æ°å¢ï¼ ``` ### 6.3 仿¬¾ç³è¯·è¯¦æ /æ°å¢é¡µé¢ æ éæ¹å¨ï¼ä»æ¬¾ç¶æä¸ºèªå¨è®¡ç®ï¼ä¸å¯æå¨ç¼è¾ã ### 6.4 æ°å¢ä»æ¬¾åé¡µé¢ **å±ç¤ºä¿¡æ¯å»ºè®®ï¼** | ä¿¡æ¯é¡¹ | 说æ | |--------|------| | 仿¬¾ç³è¯·åå· | å ³èç仿¬¾ç³è¯· | | ç³è¯·éé¢ | paymentAmount | | 已仿¬¾éé¢ | paidAmountï¼ç´¯è®¡ï¼ | | å©ä½å¯ä»æ¬¾éé¢ | paymentAmount - paidAmount | | æ¬æ¬¡ä»æ¬¾éé¢ | ç¨æ·è¾å ¥ | **æ ¡éªæç¤ºï¼** - 仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼"仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾" - è¶ é¢ä»æ¬¾ï¼"ç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢" --- ## ä¸ãAPIæ¥å£ ### 7.1 ç°ææ¥å£ï¼æ éä¿®æ¹ï¼ | æ¥å£ | æ¹æ³ | 说æ | |------|------|------| | /accountPaymentApplication/listPageAccountPaymentApplication | GET | å页æ¥è¯¢ä»æ¬¾ç³è¯· | | /accountPaymentApplication/addAccountPaymentApplication | POST | æ°å¢ä»æ¬¾ç³è¯· | | /accountPaymentApplication/updateAccountPaymentApplication | PUT | ä¿®æ¹ä»æ¬¾ç³è¯· | | /accountPaymentApplication/auditAccountPaymentApplication | PUT | å®¡æ ¸ä»æ¬¾ç³è¯· | | /accountPaymentApplication/deleteAccountPaymentApplication | DELETE | å é¤ä»æ¬¾ç³è¯· | | /accountPaymentApplication/exportAccountPaymentApplication | POST | 导åºä»æ¬¾ç³è¯· | ### 7.2 仿¬¾åæ¥å£ï¼é»è¾å·²æ´æ°ï¼ | æ¥å£ | æ¹æ³ | 说æ | |------|------|------| | /accountPurchasePayment/addAccountPurchasePayment | POST | æ°å¢ä»æ¬¾åï¼èªå¨æ´æ°payment_statusï¼ | | /accountPurchasePayment/deleteAccountPurchasePayment | DELETE | å é¤ä»æ¬¾åï¼èªå¨æ´æ°payment_statusï¼ | --- ## å «ãMapperæ¥è¯¢ä¿®æ¹å»ºè®® **AccountPaymentApplicationMapper.xml** éè¦å¨æ¥è¯¢å表æ¶å¢å 已仿¬¾éé¢ç计ç®ï¼ ```xml <select id="listPageAccountPaymentApplication" resultType="..."> SELECT apa.*, -- 计ç®å·²ä»æ¬¾éé¢ IFNULL(( SELECT SUM(app.payment_amount) FROM account_purchase_payment app WHERE app.account_payment_application_id = apa.id ), 0) AS paid_amount FROM account_payment_application apa ... </select> ``` --- ## ä¹ã注æäºé¡¹ 1. **仿¬¾ç¶æèªå¨æ´æ°ï¼** æ°å¢/å é¤ä»æ¬¾åæ¶èªå¨è®¡ç®ï¼ä¸å¯æå¨ä¿®æ¹ 2. **ç¶ææµè½¬è§åï¼** - æªä»æ¬¾(0) â é¨å仿¬¾(1)ï¼é¦æ¬¡æ°å¢ä»æ¬¾å - é¨å仿¬¾(1) â 已仿¬¾(2)ï¼ç´¯è®¡ä»æ¬¾éé¢ >= ç³è¯·éé¢ - 已仿¬¾(2) â é¨å仿¬¾(1)ï¼å é¤ä»æ¬¾ååå©ä½éé¢ < ç³è¯·éé¢ - é¨å仿¬¾(1) â æªä»æ¬¾(0)ï¼å 餿æä»æ¬¾å 3. **仿¬¾åææ¡ä»¶ï¼** 仿¬¾ç³è¯·å¿ é¡»å®¡æ ¸éè¿(status=1)æè½æ°å¢ä»æ¬¾å 4. **å岿°æ®è¿ç§»ï¼** æ°å¢å段åéæ§è¡åå§åSQL计ç®å岿°æ®ç仿¬¾ç¶æ --- ## åãæµè¯ç¨ä¾ ### 10.1 夿¬¡ä»æ¬¾æµç¨ | æ¥éª¤ | æä½ | é¢æç»æ | |------|------|----------| | 1 | æ°å¢ä»æ¬¾ç³è¯·ï¼éé¢10000å | status=0, payment_status=0 | | 2 | å®¡æ ¸éè¿ | status=1, payment_status=0 | | 3 | æ°å¢ä»æ¬¾åï¼éé¢3000å | payment_status=1(é¨å仿¬¾), paidAmount=3000 | | 4 | æ°å¢ä»æ¬¾åï¼éé¢5000å | payment_status=1(é¨å仿¬¾), paidAmount=8000 | | 5 | æ°å¢ä»æ¬¾åï¼éé¢2000å | payment_status=2(已仿¬¾), paidAmount=10000 | ### 10.2 å é¤ä»æ¬¾å | æ¥éª¤ | æä½ | é¢æç»æ | |------|------|----------| | 1 | å½åç¶æï¼payment_status=2, paidAmount=10000 | - | | 2 | å 餿åä¸ç¬ä»æ¬¾åï¼2000å ï¼ | payment_status=1, paidAmount=8000 | | 3 | å 餿æä»æ¬¾å | payment_status=0, paidAmount=0 | ### 10.3 å¼å¸¸åºæ¯ | åºæ¯ | æä½ | é¢æç»æ | |------|------|----------| | æªå®¡æ ¸ä»æ¬¾ | status=0æ¶æ°å¢ä»æ¬¾å | æç¤º"仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾" | | å®¡æ ¸ä¸éè¿ | status=2æ¶æ°å¢ä»æ¬¾å | æç¤º"仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾" | | è¶ é¢ä»æ¬¾ | ç³è¯·10000ï¼å·²ä»9000ï¼åä»2000 | æç¤º"ç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢" | docs/¸¶¿îÉêÇëÒѸ¶¿î״̬¹¦ÄÜÎĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,227 @@ # 仿¬¾ç³è¯·"已仿¬¾"ç¶æåè½ææ¡£ ## ä¸ãéæ±èæ¯ 仿¬¾ç³è¯·ï¼AccountPaymentApplicationï¼åæç¶æï¼ - 0ï¼å¾ å®¡æ ¸ - 1ï¼å®¡æ ¸éè¿ - 2ï¼å®¡æ ¸ä¸éè¿ æ°å¢ç¶æï¼ - **3ï¼å·²ä»æ¬¾** å½ä»æ¬¾ç³è¯·å ³èç仿¬¾åç´¯è®¡ä»æ¬¾éé¢çäºç³è¯·é颿¶ï¼èªå¨å°ä»æ¬¾ç³è¯·ç¶ææ´æ°ä¸º"已仿¬¾"ã --- ## äºãæ°æ®åºåæ´ï¼SQLï¼ ```sql -- æ éä¿®æ¹è¡¨ç»æï¼statusåæ®µä¸ºIntegerç±»åï¼å¯ç´æ¥æ¯ææ°ç¶æå¼ -- ç¶æè¯´æï¼ -- 0 = å¾ å®¡æ ¸ -- 1 = å®¡æ ¸éè¿ -- 2 = å®¡æ ¸ä¸éè¿ -- 3 = 已仿¬¾ï¼æ°å¢ï¼ ``` --- ## ä¸ãå端æ¹å¨ç¹ ### 3.1 å®ä½ç±»ä¿®æ¹ **AccountPaymentApplication.java** ```java /** * å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸ 1å®¡æ ¸éè¿ 2å®¡æ ¸ä¸éè¿ 3已仿¬¾ */ @ApiModelProperty("å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸ 1å®¡æ ¸éè¿ 2å®¡æ ¸ä¸éè¿ 3已仿¬¾") @Excel(name = "å®¡æ ¸ç¶æ", readConverterExp = "0=å¾ å®¡æ ¸,1=å®¡æ ¸éè¿,2=å®¡æ ¸ä¸éè¿,3=已仿¬¾") private Integer status; ``` ### 3.2 仿¬¾åæ°å¢é»è¾ï¼AccountPurchasePaymentServiceImplï¼ **æ°å¢ä»æ¬¾åæ¶çä¸å¡é»è¾ï¼** 1. æ ¡éªä»æ¬¾ç³è¯·æ¯å¦åå¨ 2. æ ¡éªä»æ¬¾ç³è¯·ç¶æå¿ 须为"å®¡æ ¸éè¿"ï¼status=1ï¼ 3. æ ¡éªç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢ 4. ä¿å仿¬¾å 5. **æ°å¢**ï¼å¦æç´¯è®¡ä»æ¬¾éé¢çäºç³è¯·éé¢ï¼èªå¨æ´æ°ä»æ¬¾ç³è¯·ç¶æä¸º"已仿¬¾"ï¼status=3ï¼ ```java // å¦æç´¯è®¡ä»æ¬¾éé¢çäºç³è¯·éé¢ï¼æ´æ°ä»æ¬¾ç³è¯·ç¶æä¸ºå·²ä»æ¬¾ if (result && accountPaymentApplication.getPaymentAmount().compareTo(newTotal) == 0) { accountPaymentApplication.setStatus(3); // 已仿¬¾ accountPaymentApplicationMapper.updateById(accountPaymentApplication); } ``` ### 3.3 仿¬¾åå é¤é»è¾ **å é¤ä»æ¬¾åæ¶çä¸å¡é»è¾ï¼** 1. æ ¡éªä»æ¬¾åæ¯å¦å·²çæå¯¹è´¦åï¼å¦æåä¸è½å é¤ 2. å é¤ä»æ¬¾å 3. **æ°å¢**ï¼å¦æä»æ¬¾ç³è¯·åç¶æä¸º"已仿¬¾"ï¼status=3ï¼ï¼å é¤åå©ä½ä»æ¬¾éé¢å°äºç³è¯·éé¢ï¼åæ¢å¤ç¶æä¸º"å®¡æ ¸éè¿"ï¼status=1ï¼ --- ## åãä¸å¡æµç¨å¾ ``` âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â 仿¬¾ç³è¯·æµç¨ â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â æ°å¢ä»æ¬¾ç³è¯· ââ⺠status=0(å¾ å®¡æ ¸) â â â â â â¼ â â âââââââââââââââ â â â å®¡æ ¸æä½ â â â âââââââââââââââ â â â â â ââââââ´âââââ â â â¼ â¼ â â éè¿ ä¸éè¿ â â â â â â â¼ â¼ â â status=1 status=2 â â (å®¡æ ¸éè¿) (å®¡æ ¸ä¸éè¿) â â â â â â¼ â â å¯ä»¥æ°å¢ä»æ¬¾å â â â â â â¼ â â âââââââââââââââââââââââââââââââââââââââ â â â ç´¯è®¡ä»æ¬¾éé¢ = ç³è¯·éé¢ï¼ â â â âââââââââââââââââââââââââââââââââââââââ â â â â â ââââââ´âââââ â â æ¯ å¦ â â â â â â â¼ â â â status=3 â â â (已仿¬¾) â â â â â â â¼ â â ç»§ç»çå¾ ä»æ¬¾ â â â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ``` --- ## äºãå端æ¹å¨ç¹ ### 5.1 仿¬¾ç³è¯·åè¡¨é¡µé¢ **ç¶æåå±ç¤ºè°æ´ï¼** | ç¶æå¼ | ç¶æåç§° | æ ç¾é¢è²ï¼å»ºè®®ï¼ | |--------|----------|------------------| | 0 | å¾ å®¡æ ¸ | warningï¼æ©è²ï¼ | | 1 | å®¡æ ¸éè¿ | successï¼ç»¿è²ï¼ | | 2 | å®¡æ ¸ä¸éè¿ | dangerï¼çº¢è²ï¼ | | 3 | 已仿¬¾ | infoï¼èè²ï¼æ primary | **åå ¸é ç½®ï¼sys_dict_data表ï¼ï¼** ```sql -- å¦æç³»ç»æåå ¸é ç½®ï¼éè¦æ·»å æ°ç¶æ INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES (4, '已仿¬¾', '3', 'payment_application_status', '', 'primary', 'N', '0', 'admin', NOW(), '', NULL, '仿¬¾ç³è¯·å·²ä»æ¬¾ç¶æ'); ``` ### 5.2 仿¬¾ç³è¯·è¯¦æ é¡µé¢ **ç¶æå±ç¤ºï¼** éè¦æ¯ææ¾ç¤º"已仿¬¾"ç¶æ ### 5.3 æ°å¢ä»æ¬¾åé¡µé¢ **åç½®æ¡ä»¶æ ¡éªæç¤ºï¼** - 妿仿¬¾ç³è¯·ç¶æä¸æ¯"å®¡æ ¸éè¿"ï¼æç¤ºï¼"仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾" - å¦æç´¯è®¡ä»æ¬¾éé¢è¶ è¿ç³è¯·éé¢ï¼æç¤ºï¼"ç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢" **å±ç¤ºä¿¡æ¯å»ºè®®ï¼** - æ¾ç¤ºä»æ¬¾ç³è¯·éé¢ - æ¾ç¤ºå·²ä»æ¬¾éé¢ï¼ç´¯è®¡ï¼ - æ¾ç¤ºå©ä½å¯ä»æ¬¾éé¢ ### 5.4 仿¬¾ç³è¯·å表çé **ç¶æçé䏿æ¡ï¼** ``` å ¨é¨ å¾ å®¡æ ¸ å®¡æ ¸éè¿ å®¡æ ¸ä¸éè¿ å·²ä»æ¬¾ï¼æ°å¢ï¼ ``` --- ## å ãAPIæ¥å£ ### 6.1 ç°ææ¥å£ï¼æ éä¿®æ¹ï¼ | æ¥å£ | æ¹æ³ | 说æ | |------|------|------| | /accountPaymentApplication/listPageAccountPaymentApplication | GET | å页æ¥è¯¢ä»æ¬¾ç³è¯·å表 | | /accountPaymentApplication/addAccountPaymentApplication | POST | æ°å¢ä»æ¬¾ç³è¯· | | /accountPaymentApplication/updateAccountPaymentApplication | PUT | ä¿®æ¹ä»æ¬¾ç³è¯· | | /accountPaymentApplication/auditAccountPaymentApplication | PUT | å®¡æ ¸ä»æ¬¾ç³è¯· | | /accountPaymentApplication/deleteAccountPaymentApplication | DELETE | å é¤ä»æ¬¾ç³è¯· | | /accountPaymentApplication/exportAccountPaymentApplication | POST | 导åºä»æ¬¾ç³è¯· | ### 6.2 仿¬¾åæ¥å£ï¼é»è¾å·²æ´æ°ï¼ | æ¥å£ | æ¹æ³ | 说æ | |------|------|------| | /accountPurchasePayment/addAccountPurchasePayment | POST | æ°å¢ä»æ¬¾åï¼èªå¨æ´æ°ä»æ¬¾ç³è¯·ç¶æï¼ | | /accountPurchasePayment/deleteAccountPurchasePayment | DELETE | å é¤ä»æ¬¾åï¼èªå¨æ¢å¤ä»æ¬¾ç³è¯·ç¶æï¼ | --- ## ä¸ã注æäºé¡¹ 1. **ç¶ææµè½¬è§åï¼** - å¾ å®¡æ ¸(0) â å®¡æ ¸éè¿(1) æ å®¡æ ¸ä¸éè¿(2) - å®¡æ ¸éè¿(1) â 已仿¬¾(3)ï¼èªå¨ï¼å½ç´¯è®¡ä»æ¬¾éé¢çäºç³è¯·éé¢ï¼ - 已仿¬¾(3) â å®¡æ ¸éè¿(1)ï¼èªå¨ï¼å½å é¤ä»æ¬¾ååå©ä½éé¢å°äºç³è¯·éé¢ï¼ 2. **å é¤ä»æ¬¾ç³è¯·æ¶ï¼** - å¦æç¶æä¸º"已仿¬¾"ï¼éè¦å å é¤å ³èç仿¬¾å - å·²çæå¯¹è´¦åç仿¬¾åä¸è½å é¤ï¼å æ¤å·²ä»æ¬¾ç¶æé常ä¸è½ç´æ¥å é¤ä»æ¬¾ç³è¯· 3. **éé¢è®¡ç®ï¼** - ç´¯è®¡ä»æ¬¾éé¢ = ææå ³è仿¬¾åçpaymentAmountä¹å - å½ç´¯è®¡ä»æ¬¾éé¢ >= ç³è¯·é颿¶ï¼ç¶æå为"已仿¬¾" --- ## å «ãæµè¯ç¨ä¾ ### 8.1 æ£å¸¸ä»æ¬¾æµç¨ | æ¥éª¤ | æä½ | é¢æç»æ | |------|------|----------| | 1 | æ°å¢ä»æ¬¾ç³è¯·ï¼éé¢10000 | status=0ï¼å¾ å®¡æ ¸ï¼ | | 2 | å®¡æ ¸éè¿ | status=1ï¼å®¡æ ¸éè¿ï¼ | | 3 | æ°å¢ä»æ¬¾åï¼éé¢6000 | status=1ï¼å®¡æ ¸éè¿ï¼ï¼ç´¯è®¡ä»æ¬¾6000 | | 4 | æ°å¢ä»æ¬¾åï¼éé¢4000 | status=3ï¼å·²ä»æ¬¾ï¼ï¼ç´¯è®¡ä»æ¬¾10000 | ### 8.2 忹仿¬¾åå é¤ | æ¥éª¤ | æä½ | é¢æç»æ | |------|------|----------| | 1 | 已仿¬¾ç³è¯·ï¼ç´¯è®¡ä»æ¬¾10000 | status=3ï¼å·²ä»æ¬¾ï¼ | | 2 | å é¤å ¶ä¸ä¸ç¬ä»æ¬¾åï¼6000ï¼ | status=1ï¼å®¡æ ¸éè¿ï¼ï¼ç´¯è®¡ä»æ¬¾4000 | ### 8.3 å¼å¸¸åºæ¯ | åºæ¯ | æä½ | é¢æç»æ | |------|------|----------| | æªå®¡æ ¸ç´æ¥ä»æ¬¾ | status=0æ¶æ°å¢ä»æ¬¾å | æç¤º"仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾" | | è¶ é¢ä»æ¬¾ | ç³è¯·10000ï¼ç´¯è®¡å·²ä»9000ï¼åä»2000 | æç¤º"ç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢" | docs/ÏúÊŲ̂ÕËÏÖÔÚÉú²ú×Ö¶Îͬ²½Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,263 @@ # éå®å°è´¦"ç°å¨ç产"åæ®µåæ¥ä¼åææ¡£ ## ä¸ãéæ±èæ¯ æ°å¢éå®å°è´¦æ¶ï¼å¦æå¾é"ç°å¨ç产"ï¼éè¦å°ä»¥ä¸åæ®µåæ¥å°ä¸»ç产计ååç产订åï¼ 1. **åä½**ï¼ä»äº§åè§æ ¼åæ¥ 2. **äº§åæ°é**ï¼ä½ä¸ºä¸»è®¡åæéæ°é 3. **æ»æ°**å**æ¯ä»¶æ°é**ï¼åæ¥å°ç产侧ï¼ç¨äºå ¥åºæ¶è®¡ç®å®é å ¥åºé ### ä¸å¡è§å - **主计åæéæ°é** = äº§åæ°éï¼quantityï¼ï¼ä¸æ¯æ»æ° - **çäº§å ¥åºæ°é** = æ¥å·¥æ°é à æ¯ä»¶æ°éï¼singleQuantityï¼ --- ## äºãæ°æ®åºåæ´ï¼SQLï¼ ```sql -- ===================================================== -- 1. 主ç产计å表æ°å¢å段 -- ===================================================== ALTER TABLE `production_plan` ADD COLUMN `unit` VARCHAR(50) NULL COMMENT 'åä½' AFTER `product_model_id`, ADD COLUMN `quantity` DECIMAL(24,6) NULL COMMENT 'äº§åæ°é' AFTER `unit`, ADD COLUMN `single_quantity` DECIMAL(24,6) NULL COMMENT 'æ¯ä»¶æ°é' AFTER `quantity`, ADD COLUMN `total_quantity` DECIMAL(24,6) NULL COMMENT 'æ»æ°' AFTER `single_quantity`; -- ===================================================== -- 2. ç产订å表æ°å¢å段 -- ===================================================== ALTER TABLE `production_order` ADD COLUMN `unit` VARCHAR(50) NULL COMMENT 'åä½' AFTER `product_model_id`, ADD COLUMN `single_quantity` DECIMAL(24,6) NULL COMMENT 'æ¯ä»¶æ°é' AFTER `quantity`, ADD COLUMN `total_quantity` DECIMAL(24,6) NULL COMMENT 'æ»æ°' AFTER `single_quantity`; -- ===================================================== -- 3. å岿°æ®è¿ç§»ï¼å¯éï¼ä»äº§åè§æ ¼è¡¨åå¡«åä½ï¼ -- ===================================================== -- æ´æ°ä¸»ç产计åçåä½ UPDATE production_plan pp LEFT JOIN product_model pm ON pp.product_model_id = pm.id SET pp.unit = pm.unit WHERE pp.unit IS NULL; -- æ´æ°ç产订åçåä½ UPDATE production_order po LEFT JOIN product_model pm ON po.product_model_id = pm.id SET po.unit = pm.unit WHERE po.unit IS NULL; -- ===================================================== -- 4. åæ®µè¯´æ -- ===================================================== -- production_plan è¡¨åæ®µï¼ -- qty_required - éæ±æ°éï¼åæåæ®µï¼æ¹ä¸ºåå¨äº§åæ°é quantityï¼ -- unit - åä½ï¼æ°å¢ï¼ -- quantity - äº§åæ°éï¼æ°å¢ï¼ -- single_quantity - æ¯ä»¶æ°éï¼æ°å¢ï¼ -- total_quantity - æ»æ°ï¼æ°å¢ï¼ -- -- production_order è¡¨åæ®µï¼ -- quantity - éæ±æ°éï¼åæå段ï¼ä¿æä¸åï¼ -- unit - åä½ï¼æ°å¢ï¼ -- single_quantity - æ¯ä»¶æ°éï¼æ°å¢ï¼ -- total_quantity - æ»æ°ï¼æ°å¢ï¼ ``` --- ## ä¸ãå端æ¹å¨ç¹ ### 3.1 å®ä½ç±»ä¿®æ¹ #### ProductionPlan.javaï¼ä¸»ç产计åï¼ æ°å¢åæ®µï¼ ```java @Schema(description = "åä½") private String unit; @Schema(description = "äº§åæ°é") private BigDecimal quantity; @Schema(description = "æ¯ä»¶æ°é") private BigDecimal singleQuantity; @Schema(description = "æ»æ°") private BigDecimal totalQuantity; ``` #### ProductionOrder.javaï¼ç产订åï¼ æ°å¢åæ®µï¼ ```java @Schema(description = "åä½") private String unit; @Schema(description = "æ¯ä»¶æ°é") private BigDecimal singleQuantity; @Schema(description = "æ»æ°") private BigDecimal totalQuantity; ``` ### 3.2 SalesLedgerProductServiceImpl.addProductionData() æ¹æ³ä¿®æ¹ **ä¿®æ¹å**ï¼ ```java productionPlan.setQtyRequired(normalizeTotalQuantity( salesLedgerProduct.getTotalQuantity(), salesLedgerProduct.getQuantity(), salesLedgerProduct.getSingleQuantity() )); // éæ±æ°é = æ»æ° ``` **ä¿®æ¹å**ï¼ ```java // æ¥è¯¢äº§åè§æ ¼è·ååä½ ProductModel productModel = productModelMapper.selectById(salesLedgerProduct.getProductModelId()); productionPlan.setQtyRequired(salesLedgerProduct.getQuantity()); // éæ±æ°é = äº§åæ°é productionPlan.setUnit(productModel != null ? productModel.getUnit() : null); // åä½ productionPlan.setQuantity(salesLedgerProduct.getQuantity()); // äº§åæ°é productionPlan.setSingleQuantity(normalizeSingleQuantity(salesLedgerProduct.getSingleQuantity())); // æ¯ä»¶æ°é productionPlan.setTotalQuantity(normalizeTotalQuantity( salesLedgerProduct.getTotalQuantity(), salesLedgerProduct.getQuantity(), salesLedgerProduct.getSingleQuantity() )); // æ»æ° ``` ### 3.3 ç产计åä¸åå°çäº§è®¢åæ¶åæ¥åæ®µ å¨ `ProductionPlanServiceImpl.combine()` æ¹æ³ä¸ï¼åå¹¶ä¸åçäº§è®¢åæ¶ï¼éè¦åæ¥ä»¥ä¸åæ®µï¼ - unitï¼åä½ï¼ - singleQuantityï¼æ¯ä»¶æ°éï¼ - totalQuantityï¼æ»æ°ï¼ ### 3.4 çäº§å ¥åºæ°é计ç®ä¿®æ¹ **ä¿®æ¹ä½ç½®**ï¼`ProductionProductMainServiceImpl.addProductMainByProductionTask()` æ¹æ³ **ä¿®æ¹é»è¾**ï¼ ```java // è·åç产订åå ³èçæ¯ä»¶æ°é ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId()); BigDecimal singleQuantity = productionOrder.getSingleQuantity(); if (singleQuantity == null || singleQuantity.compareTo(BigDecimal.ZERO) <= 0) { singleQuantity = BigDecimal.ONE; } // å ¥åºæ°é = æ¥å·¥æ°é à æ¯ä»¶æ°é BigDecimal stockInQuantity = productQty.multiply(singleQuantity); // å ¥åºè®°å½ StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setQualitity(stockInQuantity); // 使ç¨è®¡ç®åçå ¥åºæ°é ``` --- ## åãå端æ¹å¨ç¹ ### 4.1 éå®å°è´¦æ°å¢/ç¼è¾é¡µé¢ æ éä¿®æ¹ï¼"ç°å¨ç产"å¼å ³å·²åå¨ï¼å端èªå¨åæ¥æ°æ®å°ç产计åã ### 4.2 主ç产计ååè¡¨é¡µé¢ æ°å¢å±ç¤ºåï¼ | åæ®µ | åå | 说æ | |------|------|------| | unit | åä½ | ä»äº§åè§æ ¼åæ¥ | | quantity | äº§åæ°é | å qtyRequired æ¹åææ°å¢å±ç¤º | | singleQuantity | æ¯ä»¶æ°é | æ°å¢å±ç¤º | | totalQuantity | æ»æ° | æ°å¢å±ç¤º | ### 4.3 ç产订ååè¡¨é¡µé¢ æ°å¢å±ç¤ºåï¼ | åæ®µ | åå | 说æ | |------|------|------| | unit | åä½ | ä»ç产计å忥 | | singleQuantity | æ¯ä»¶æ°é | æ°å¢å±ç¤º | | totalQuantity | æ»æ° | æ°å¢å±ç¤º | ### 4.4 çäº§å ¥åº/æ¥å·¥é¡µé¢ **å±ç¤ºè°æ´**ï¼ - æ¥å·¥æ°éï¼ç¨æ·è¾å ¥çäº§åæ°é - å®é å ¥åºæ°éï¼èªå¨è®¡ç® = æ¥å·¥æ°é à æ¯ä»¶æ°é **å端计ç®å±ç¤ºç¤ºä¾**ï¼ ```javascript // æ¥å·¥è¡¨å const reportForm = { quantity: 0, // æ¥å·¥æ°éï¼äº§åæ°éï¼ singleQuantity: 1, // æ¯ä»¶æ°éï¼ä»ç产订å带åºï¼åªè¯»ï¼ actualQuantity: 0 // å®é å ¥åºæ°é = quantity à singleQuantity }; // 计ç®å®é å ¥åºæ°é const calcActualQuantity = () => { const qty = reportForm.quantity || 0; const single = reportForm.singleQuantity || 1; reportForm.actualQuantity = qty * single; }; ``` --- ## äºãæ°æ®æµè½¬å¾ ``` âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â éå®å°è´¦äº§å â â SalesLedgerProduct â â ââ quantity (äº§åæ°é) âââââââââââââââââââ â â ââ singleQuantity (æ¯ä»¶æ°é) âââââââââââââ¼ââââ â â ââ totalQuantity (æ»æ°) ââââââââââââââââââ¼ââââ¼ââââ â â ââ unit (åä½ï¼æ¥èªproduct_model) ââââââââ¼ââââ¼ââââ¼ââââ â â ââ isProduction = true âââââââââââââââââââ â â â â ââââââââââââââââââââââââââââââââââââââââââââââââââ â â â â â â â â â¼ â¼ â¼ â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â 主ç产计å â â ProductionPlan â â ââ qtyRequired (éæ±æ°é) = quantity (äº§åæ°é) â â ââ quantity (äº§åæ°é) âââââââââââââââââââââââââââââââââââââââ â â ââ singleQuantity (æ¯ä»¶æ°é) âââââââââââââââââââââââââââââââââ â â ââ totalQuantity (æ»æ°) ââââââââââââââââââââââââââââââââââââââ â â ââ unit (åä½) âââââââââââââââââââââââââââââââââââââââââââââââ â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â âââ â ä¸åå°ç产订å âââ â â¼â¼â¼ â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â ç产订å â â ProductionOrder â â ââ quantity (éæ±æ°é) â â ââ singleQuantity (æ¯ä»¶æ°é) â â ââ totalQuantity (æ»æ°) â â ââ unit (åä½) â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â¼ âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â ç产æ¥å·¥ â â ProductionProductMain â â ââ æ¥å·¥æ°é (quantity) â â ââ å®é å ¥åºæ°é = æ¥å·¥æ°é à æ¯ä»¶æ°é â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ``` --- ## å ãæ³¨æäºé¡¹ 1. **å岿°æ®å ¼å®¹**ï¼å岿°æ® `singleQuantity` é»è®¤ä¸º 1ï¼å ¥åºæ°é计ç®ä¸åå½±å 2. **åæ®µä¼å 级**ï¼ - 主计åæéæ°é `qtyRequired` æ¹ä¸ºåå¨äº§åæ°é `quantity` - æ»æ° `totalQuantity` = quantity à singleQuantityï¼åä½åå¨ï¼ä¾¿äºæ¥è¯¢å±ç¤ºï¼ 3. **å使¥æº**ï¼åä½ä» `product_model` è¡¨åæ¥ï¼éå®å°è´¦å表æ¬èº«ä¸åå¨åä½ 4. **ç¼è¾åæ¥**ï¼éå®å°è´¦äº§åç¼è¾æ¶ï¼ä¼å 餿§ç产计åå¹¶éæ°å建ï¼å¦ææªä¸åï¼ src/main/java/com/ruoyi/account/bean/dto/purchase/AccountPaymentApplicationDto.java
@@ -19,6 +19,9 @@ @Schema(description = "å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸1å®¡æ ¸éè¿2å®¡æ ¸ä¸éè¿") private Integer status; @Schema(description = "仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾") private Integer paymentStatus; @Schema(description = "å¼å§æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") src/main/java/com/ruoyi/account/bean/vo/purchase/AccountPaymentApplicationVo.java
@@ -6,6 +6,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; @Data @Schema(name = "AccountPaymentApplicationVo", description = "è´¢å¡ç®¡ç--仿¬¾ç³è¯·å°è´¦(è¿å)") @ExcelIgnoreUnannotated @@ -19,5 +21,8 @@ @Excel(name = "å ¥åºåå·") private String inboundBatches; @Schema(description = "已仿¬¾éé¢") @Excel(name = "已仿¬¾éé¢") private BigDecimal paidAmount; } src/main/java/com/ruoyi/account/pojo/purchase/AccountPaymentApplication.java
@@ -131,6 +131,20 @@ @ApiModelProperty("å®¡æ ¸ç¶æ:0å¾ å®¡æ ¸1å®¡æ ¸éè¿2å®¡æ ¸ä¸éè¿") @Excel(name = "å®¡æ ¸ç¶æ",readConverterExp = "0=å¾ å®¡æ ¸,1=å®¡æ ¸éè¿,2=å®¡æ ¸ä¸éè¿") private Integer status; /** * 仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾ */ @ApiModelProperty("仿¬¾ç¶æ:0æªä»æ¬¾ 1é¨å仿¬¾ 2已仿¬¾") @Excel(name = "仿¬¾ç¶æ",readConverterExp = "0=æªä»æ¬¾,1=é¨å仿¬¾,2=已仿¬¾") private Integer paymentStatus; /** * 已仿¬¾éé¢ */ @ApiModelProperty("已仿¬¾éé¢") @TableField(exist = false) private BigDecimal paidAmount; /** * 仿¬¾éé¢ src/main/java/com/ruoyi/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java
@@ -54,14 +54,31 @@ if (StringUtils.isEmpty(accountPurchasePayment.getPaymentNumber())) { accountPurchasePayment.setPaymentNumber(genAccountPurchasePaymentNo()); } //æ ¡éªç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢ //æ ¡éªä»æ¬¾ç³è¯·æ¯å¦åå¨ä¸å®¡æ ¸éè¿ AccountPaymentApplication accountPaymentApplication = accountPaymentApplicationMapper.selectById(accountPurchasePayment.getAccountPaymentApplicationId()); List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectList(Wrappers.<AccountPurchasePayment>lambdaQuery().eq(AccountPurchasePayment::getAccountPaymentApplicationId, accountPurchasePayment.getAccountPaymentApplicationId())); BigDecimal totalPaymentAmount = accountPurchasePayments.stream().map(AccountPurchasePayment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add); if (accountPaymentApplication.getPaymentAmount().compareTo(totalPaymentAmount) < 0) { if (accountPaymentApplication == null) { throw new ServiceException("仿¬¾ç³è¯·ä¸åå¨"); } if (accountPaymentApplication.getStatus() == null || accountPaymentApplication.getStatus() != 1) { throw new ServiceException("仿¬¾ç³è¯·æªå®¡æ ¸éè¿ï¼ä¸è½ä»æ¬¾"); } //æ ¡éªç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢ List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectList( Wrappers.<AccountPurchasePayment>lambdaQuery() .eq(AccountPurchasePayment::getAccountPaymentApplicationId, accountPurchasePayment.getAccountPaymentApplicationId())); BigDecimal totalPaymentAmount = accountPurchasePayments.stream() .map(AccountPurchasePayment::getPaymentAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal newTotal = totalPaymentAmount.add(accountPurchasePayment.getPaymentAmount()); if (newTotal.compareTo(accountPaymentApplication.getPaymentAmount()) > 0) { throw new ServiceException("ç´¯è®¡ä»æ¬¾éé¢ä¸è½è¶ è¿ç³è¯·éé¢"); } return save(accountPurchasePayment); boolean result = save(accountPurchasePayment); // æ´æ°ä»æ¬¾ç³è¯·ç仿¬¾ç¶æ if (result) { updatePaymentStatus(accountPaymentApplication, newTotal); } return result; } @Override @@ -73,6 +90,9 @@ @Override public boolean deleteAccountPurchasePayment(List<Long> ids) { if (CollectionUtils.isEmpty(ids)) { return false; } //å¦æè¯¥ä»æ¬¾åå·²ç»çæå¯¹è´¦ååæ æ³å é¤ List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectByIds(ids); List<String> strings = accountPurchasePayments.stream().map(AccountPurchasePayment::getPaymentNumber).toList(); @@ -81,7 +101,47 @@ if (CollectionUtils.isNotEmpty(accountStatementDetails)){ throw new ServiceException("è¯¥ä»æ¬¾åå·²ç»çæå¯¹è´¦åï¼æ æ³å é¤"); } return removeByIds(ids); boolean result = removeByIds(ids); // å 餿ååï¼æ´æ°ä»æ¬¾ç³è¯·ç仿¬¾ç¶æ if (result) { for (AccountPurchasePayment payment : accountPurchasePayments) { if (payment.getAccountPaymentApplicationId() != null) { AccountPaymentApplication application = accountPaymentApplicationMapper.selectById(payment.getAccountPaymentApplicationId()); if (application != null) { // 计ç®å©ä½ä»æ¬¾éé¢ List<AccountPurchasePayment> remainingPayments = accountPurchasePaymentMapper.selectList( Wrappers.<AccountPurchasePayment>lambdaQuery() .eq(AccountPurchasePayment::getAccountPaymentApplicationId, application.getId())); BigDecimal remainingAmount = remainingPayments.stream() .map(AccountPurchasePayment::getPaymentAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); updatePaymentStatus(application, remainingAmount); } } } } return result; } /** * æ´æ°ä»æ¬¾ç³è¯·ç仿¬¾ç¶æ * @param application 仿¬¾ç³è¯· * @param paidAmount 已仿¬¾éé¢ */ private void updatePaymentStatus(AccountPaymentApplication application, BigDecimal paidAmount) { BigDecimal applyAmount = application.getPaymentAmount(); int newPaymentStatus; if (paidAmount.compareTo(BigDecimal.ZERO) == 0) { newPaymentStatus = 0; // æªä»æ¬¾ } else if (paidAmount.compareTo(applyAmount) < 0) { newPaymentStatus = 1; // é¨å仿¬¾ } else { newPaymentStatus = 2; // 已仿¬¾ } if (application.getPaymentStatus() == null || application.getPaymentStatus() != newPaymentStatus) { application.setPaymentStatus(newPaymentStatus); accountPaymentApplicationMapper.updateById(application); } } private String genAccountPurchasePaymentNo() { src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java
@@ -76,6 +76,14 @@ productionOperationTaskService.down(response, dto); } @GetMapping("/byOrder/{orderId}") @Operation(summary = "æ ¹æ®ç产订åIDæ¥è¯¢åç»æ°æ®") public R<List<ProductionOperationTaskVo>> byOrder(@PathVariable Long orderId) { ProductionOperationTaskDto dto = new ProductionOperationTaskDto(); dto.setProductionOrderId(orderId); return R.ok(productionOperationTaskService.listProductionOperationTask(dto)); } @GetMapping("/getOperation") @Operation(summary = "å·¥åºè¯¦æ æ¥è¯¢") public R<List<ProductionOperationTaskVo>> getOperation(ProductionOperationTaskDto dto) { src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java
@@ -43,4 +43,6 @@ ProductionOperationTaskDto getProductWorkOrderFlowCard(@Param("id") Long id); List<ProductionOperationTaskVo> getOperation(@Param("c") ProductionOperationTaskDto dto); List<ProductionOperationTaskVo> listGroupedProductionOperationTask(@Param("c") ProductionOperationTaskDto dto); } src/main/java/com/ruoyi/production/pojo/ProductionPlan.java
@@ -68,6 +68,18 @@ @Schema(description = "产ååå·id") private Long productModelId; @Schema(description = "åä½") private String unit; @Schema(description = "äº§åæ°é") private BigDecimal quantity; @Schema(description = "æ¯ä»¶æ°é") private BigDecimal singleQuantity; @Schema(description = "æ»æ°") private BigDecimal totalQuantity; @Schema(description = "éæ±æ°é") private BigDecimal qtyRequired; src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
@@ -71,8 +71,8 @@ @Override public List<ProductionOperationTaskVo> listProductionOperationTask(ProductionOperationTaskDto dto) { // æ¥è¯¢å·¥åºä»»å¡å表 List<ProductionOperationTaskVo> result = BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOperationTaskVo.class); // æç产订ååç»æ¥è¯¢å·¥åºä»»å¡å表 List<ProductionOperationTaskVo> result = baseMapper.listGroupedProductionOperationTask(dto); fillOperationTypes(result); fillUserNames(result); return result; src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.framework.web.domain.R; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.mapper.*; @@ -86,6 +88,8 @@ private StockUtils stockUtils; @Autowired private StockInventoryMapper stockInventoryMapper; @Autowired private ProductModelMapper productModelMapper; @Override public SalesLedgerProduct selectSalesLedgerProductById(Long id) { @@ -225,12 +229,28 @@ return; } SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerProduct.getSalesLedgerId()); // è·ååä½ï¼ä¼å 使ç¨åç«¯ä¼ å ¥çunitï¼å¦åä»äº§åè§æ ¼è·å String unit = salesLedgerProduct.getUnit(); if (unit == null || unit.isEmpty()) { ProductModel productModel = productModelMapper.selectById(salesLedgerProduct.getProductModelId()); unit = productModel != null ? productModel.getUnit() : null; } ProductionPlan productionPlan = new ProductionPlan(); productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId()); productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId()); productionPlan.setMpsNo(generateNextPlanNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")))); productionPlan.setProductModelId(salesLedgerProduct.getProductModelId()); productionPlan.setQtyRequired(normalizeTotalQuantity( // éæ±æ°é = äº§åæ°éï¼ä¸æ¯æ»æ°ï¼ productionPlan.setQtyRequired(salesLedgerProduct.getQuantity()); // 忥åä½ productionPlan.setUnit(unit); // åæ¥äº§åæ°é productionPlan.setQuantity(salesLedgerProduct.getQuantity()); // 忥æ¯ä»¶æ°é productionPlan.setSingleQuantity(normalizeSingleQuantity(salesLedgerProduct.getSingleQuantity())); // åæ¥æ»æ° productionPlan.setTotalQuantity(normalizeTotalQuantity( salesLedgerProduct.getTotalQuantity(), salesLedgerProduct.getQuantity(), salesLedgerProduct.getSingleQuantity() src/main/resources/mapper/account/purchase/AccountPaymentApplicationMapper.xml
@@ -18,6 +18,7 @@ <result column="apply_date" property="applyDate" /> <result column="remark" property="remark" /> <result column="status" property="status" /> <result column="payment_status" property="paymentStatus" /> <result column="payment_amount" property="paymentAmount" /> </resultMap> <select @@ -25,7 +26,8 @@ resultType="com.ruoyi.account.bean.vo.purchase.AccountPaymentApplicationVo"> select * from (select apa.*, sm.supplier_name, GROUP_CONCAT(sir.inbound_batches SEPARATOR ',') AS inboundBatches GROUP_CONCAT(sir.inbound_batches SEPARATOR ',') AS inboundBatches, IFNULL((SELECT SUM(app.payment_amount) FROM account_purchase_payment app WHERE app.account_payment_application_id = apa.id), 0) AS paidAmount from account_payment_application apa left join supplier_manage sm on apa.supplier_id = sm.id left join stock_in_record sir on FIND_IN_SET(sir.id, apa.stock_in_record_ids) > 0 @@ -40,6 +42,9 @@ <if test="req.status != null"> AND A.status = #{req.status} </if> <if test="req.paymentStatus != null"> AND A.payment_status = #{req.paymentStatus} </if> <if test="req.startDate != null and req.endDate != null"> AND A.apply_date BETWEEN #{req.startDate} AND #{req.endDate} </if> src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
@@ -21,21 +21,29 @@ <result column="dept_id" property="deptId" /> </resultMap> <select id="pageProductionOperationTask" resultType="com.ruoyi.production.bean.vo.ProductionOperationTaskVo"> select pot.*, <sql id="groupedProductionOperationTaskSelect"> select po.id as productionOrderId, po.nps_no as npsNo, po.is_end_order as endOrder, p.product_name as productName, pm.model as model, pm.unit as unit, poro.operation_name as operationName, poro.type as type, IFNULL(scrapStat.scrapQty, 0) AS scrapQty, ROUND(IFNULL(pot.complete_quantity, 0) / NULLIF(pot.plan_quantity, 0) * 100, 2) AS completionStatus, CASE WHEN pot.work_order_no LIKE 'FG%' THEN 'è¿å·¥è¿ä¿®' ELSE 'æ£å¸¸' END AS work_order_type group_concat(distinct poro.operation_name order by poro.drag_sort, poro.operation_name separator ',') as operationName, count(distinct pot.id) as productionTaskCount, sum(ifnull(pot.plan_quantity, 0)) as planQuantity, sum(ifnull(pot.complete_quantity, 0)) as completeQuantity, sum(ifnull(pot.complete_quantity, 0)) as goodQuantity, sum(ifnull(scrapStat.scrapQty, 0)) as scrapQty, round(sum(ifnull(pot.complete_quantity, 0)) / nullif(sum(ifnull(pot.plan_quantity, 0)), 0) * 100, 2) as completionStatus, max(poro.type) as type, case when sum(case when pot.work_order_no like 'FG%' then 1 else 0 end) > 0 then 'è¿å·¥è¿ä¿®' else 'æ£å¸¸' end as workOrderType, group_concat(distinct pot.work_order_no order by pot.work_order_no separator ',') as workOrderNo, min(pot.plan_start_time) as planStartTime, max(pot.plan_end_time) as planEndTime, min(pot.actual_start_time) as actualStartTime, max(pot.actual_end_time) as actualEndTime, max(pot.status) as status from production_operation_task pot left join production_order po on pot.production_order_id = po.id left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id @@ -48,30 +56,31 @@ left join production_product_output ppo on ppo.production_product_main_id = ppm.id group by ppm.production_operation_task_id ) scrapStat on scrapStat.taskId = pot.id </sql> <sql id="groupedProductionOperationTaskWhere"> <where> <if test="c != null and c.id != null"> and pot.id = #{c.id} </if> <if test="c != null and c.npsNo != null"> <if test="c != null and c.npsNo != null and c.npsNo != ''"> and po.nps_no like concat('%', #{c.npsNo}, '%') </if> <if test="c != null and c.productionOrderId != null"> and pot.production_order_id = #{c.productionOrderId} </if> <if test="c != null and c.productionOrderRoutingOperationId != null"> and pot.production_order_routing_operation_id = #{c.productionOrderRoutingOperationId} </if> <if test="c != null and c.status != null"> and pot.status = #{c.status} </if> <if test="c != null and c.isProduction != null"> and poro.is_production = #{c.isProduction} </if> <if test="c != null and c.workOrderNo != null and c.workOrderNo != ''"> and pot.work_order_no like concat('%', #{c.workOrderNo}, '%') </if> </where> order by pot.id desc </sql> <select id="pageProductionOperationTask" resultType="com.ruoyi.production.bean.vo.ProductionOperationTaskVo"> <include refid="groupedProductionOperationTaskSelect"/> <include refid="groupedProductionOperationTaskWhere"/> group by po.id order by po.id desc </select> <select id="listGroupedProductionOperationTask" resultType="com.ruoyi.production.bean.vo.ProductionOperationTaskVo"> <include refid="groupedProductionOperationTaskSelect"/> <include refid="groupedProductionOperationTaskWhere"/> group by po.id, po.nps_no, po.is_end_order, p.product_name, pm.model, pm.unit order by po.id desc </select> <select id="selectTaskStatisticsByDate" resultType="com.ruoyi.home.dto.ProductionTaskStatisticsDto">