From f8b236340b16d9dfe2ca88407343ac01f34f3cbf Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期四, 21 五月 2026 15:09:42 +0800
Subject: [PATCH] Merge branch 'dev_New_pro' into dev_New_pro_财务

---
 src/main/java/com/ruoyi/ai/assistant/SalesAgent.java                                            |    4 
 src/main/java/com/ruoyi/home/controller/HomeController.java                                     |  146 +++++-
 src/main/java/com/ruoyi/ai/tools/PurchaseAgentTools.java                                        |   64 ++
 src/main/resources/manufacturing-agent-prompt.txt                                               |    2 
 doc/20260521_首页HomeController接口升级前端变更文档.md                                                      |  113 +++++
 src/main/java/com/ruoyi/ai/controller/SalesAiController.java                                    |   12 
 src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java                   |    5 
 doc/20260521_采购智能体优化前端变更文档.md                                                                   |   85 ++++
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java |  149 ++++++
 src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java             |    2 
 src/main/resources/approve-todo-agent-prompt.txt                                                |    2 
 src/main/java/com/ruoyi/ai/assistant/ApproveTodoAgent.java                                      |    3 
 src/main/java/com/ruoyi/quality/controller/QualityReportController.java                         |   34 +
 src/main/java/com/ruoyi/ai/assistant/PurchaseAgent.java                                         |    3 
 src/main/java/com/ruoyi/ai/controller/ManufacturingAiController.java                            |   12 
 src/main/java/com/ruoyi/ai/service/PurchaseAiService.java                                       |   64 ++
 src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java                   |   10 
 src/main/resources/mapper/production/ProductionOrderMapper.xml                                  |   30 +
 src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java                            |   18 
 src/main/resources/purchase-agent-prompt.txt                                                    |    9 
 src/main/resources/sales-agent-prompt.txt                                                       |    2 
 src/main/resources/mapper/production/ProductionOperationTaskMapper.xml                          |    3 
 src/main/java/com/ruoyi/quality/controller/QualityInspectController.java                        |   10 
 src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java                    |    9 
 src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java                                |  249 ++++++++--
 src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java          |    2 
 src/main/java/com/ruoyi/ai/controller/XiaozhiController.java                                    |   11 
 src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java          |    3 
 src/main/java/com/ruoyi/quality/controller/QualityTestStandardBindingController.java            |    5 
 src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java                     |    3 
 src/main/java/com/ruoyi/quality/controller/QualityTestStandardParamController.java              |    6 
 src/main/java/com/ruoyi/ai/assistant/ManufacturingAgent.java                                    |    3 
 src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java                               |  137 ++++++
 33 files changed, 1,071 insertions(+), 139 deletions(-)

diff --git "a/doc/20260521_\351\207\207\350\264\255\346\231\272\350\203\275\344\275\223\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md" "b/doc/20260521_\351\207\207\350\264\255\346\231\272\350\203\275\344\275\223\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..58089e8
--- /dev/null
+++ "b/doc/20260521_\351\207\207\350\264\255\346\231\272\350\203\275\344\275\223\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
@@ -0,0 +1,85 @@
+# 閲囪喘鏅鸿兘浣撲紭鍖栧墠绔彉鏇存枃妗�
+
+## 1. 鍙樻洿鑳屾櫙
+
+鏈閽堝閲囪喘鏅鸿兘浣撳仛浜嗗榻愪紭鍖栵紙鍙傝�冮攢鍞�/瀹℃壒/鍒堕�犳櫤鑳戒綋锛夛細
+
+1. 鎻愬崌 `quickPrompts` 鍛戒腑绋冲畾鎬с��
+2. 澧炲己鐩稿鏃堕棿璇嗗埆锛堜粖澶�/鏄ㄥぉ/鏈懆/涓婂懆/鏈湀/涓婃湀/浠婂勾/鍘诲勾/杩慛澶╃瓑锛夈��
+3. 澧炲姞涓氬姟鎰忓浘鏈瘑鍒椂鐨勭粨鏋勫寲鍏滃簳鍝嶅簲锛岄伩鍏嶇紪閫犳暟鎹��
+4. 琛ュ厖寰呬粯娆炬煡璇㈢殑姹囨�诲瓧娈碉紝渚夸簬鍓嶇鐩存帴娓叉煋缁熻鍗$墖銆�
+
+## 2. 鎺ュ彛褰卞搷姒傝
+
+| 鎺ュ彛 | 鏂规硶 | 鏄惁鏀硅矾寰� | 鏄惁鏀瑰叆鍙� | 鏄惁鏀硅繑鍥炵粨鏋� |
+| --- | --- | --- | --- | --- |
+| `/purchase-ai/chat` | POST(SSE) | 鍚� | 鍚� | 鏄紙鏂板鍏滃簳 JSON 绫诲瀷锛� |
+| `/purchase-ai/analyze-files` | POST(SSE) | 鍚� | 鍚� | 鍚︼紙浠呭唴閮ㄦ彁绀鸿瘝澧炲己锛� |
+
+## 3. 鏂板鍏滃簳鍝嶅簲锛堥噸鐐癸級
+
+褰撶敤鎴锋槑鏄惧湪闂噰璐笟鍔★紝浣嗘潯浠朵笉鍏呭垎涓旀湭鍛戒腑鍙墽琛屾剰鍥炬椂锛宍/purchase-ai/chat` 浼氱洿鎺ヨ繑鍥炵粨鏋勫寲 JSON锛堣�屼笉鏄嚜鐢辨枃鏈級锛�
+
+```json
+{
+  "success": false,
+  "type": "purchase_intent_not_recognized",
+  "description": "鏈瘑鍒埌鍙墽琛岀殑閲囪喘鏌ヨ鏉′欢銆備负淇濊瘉缁撴灉鍑嗙‘锛屽綋鍓嶄笉浼氭帹娴嬫垨缂栭�犳暟鎹紝璇疯ˉ鍏呮槑纭椂闂磋寖鍥淬�佷緵搴斿晢銆侀噰璐悎鍚屽彿鎴栫墿鏂欏悗鍐嶆煡璇€��",
+  "summary": {},
+  "data": {
+    "quickPrompts": [
+      "鏈湀閲囪喘閲戦鎺掑悕鍓嶅崄鐨勭墿鏂欐湁鍝簺锛�",
+      "鍝簺閲囪喘璁㈠崟杩樻湭鍏ュ簱锛�",
+      "鏈�杩�7澶╀緵搴斿晢鍒拌揣寮傚父鏈夊摢浜涳紵",
+      "甯垜缁熻寰呬粯娆鹃噰璐崟锛�",
+      "鍒楀嚭鏈湀閲囪喘閫�璐ф儏鍐�"
+    ]
+  },
+  "charts": {}
+}
+```
+
+鍓嶇澶勭悊寤鸿锛�
+
+1. 褰� `type === "purchase_intent_not_recognized"` 鏃讹紝灞曠ず `description`銆�
+2. 璇诲彇 `data.quickPrompts` 浣滀负蹇嵎鎻愰棶鎸夐挳锛堝彲鐩存帴鍥炲~杈撳叆妗嗭級銆�
+
+## 4. 寰呬粯娆捐繑鍥炴柊澧炴眹鎬诲瓧娈�
+
+鎺ュ彛绫诲瀷锛歚type = "purchase_pending_payment_list"`  
+浣嶇疆锛歚summary`
+
+鏂板瀛楁锛�
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+| --- | --- | --- |
+| pendingOrderCount | number | 寰呬粯娆捐鍗曟暟 |
+| totalContractAmount | number | 寰呬粯娆捐鍗曞悎鍚屾�婚 |
+| totalPaidAmount | number | 宸蹭粯娆炬�婚 |
+| totalPendingAmount | number | 寰呬粯娆炬�婚 |
+
+璇存槑锛氬師鏈夊瓧娈典粛淇濈暀锛堝吋瀹癸級锛屾湰娆′负澧為噺瀛楁锛屼笉鐮村潖鐜版湁娓叉煋銆�
+
+## 5. 鏃堕棿鍙e緞浼樺寲
+
+閲囪喘鏅鸿兘浣撶幇鍦ㄧ粺涓�鎸変腑鍥芥椂鍖哄姩鎬佹棩鏈熸崲绠楃浉瀵规椂闂达紝鏀寔锛�
+
+- 浠婂ぉ銆佹槰澶�
+- 鏈懆銆佷笂鍛�
+- 鏈湀銆佷笂鏈�
+- 浠婂勾銆佸幓骞�
+- 杩慛澶�/鍛�/鏈�/骞淬�佽繎鍗婂勾銆佽繎鍗婁釜鏈�
+
+鍓嶇鏃犻渶鏀逛紶鍙傦紝浣嗗睍绀烘椂闂磋寖鍥存椂璇蜂互鍚庣杩斿洖 `summary.startDate/endDate/timeRange` 涓哄噯銆�
+
+## 6. 鍓嶇鑱旇皟妫�鏌ユ竻鍗�
+
+1. `chat` 娴佸紡缁撴灉鎷兼帴鍚庯紝浼樺厛鎸� JSON 瑙f瀽銆�
+2. 瑕嗙洊鏂扮被鍨� `purchase_intent_not_recognized` 鐨� UI 澶勭悊銆�
+3. 寰呬粯娆鹃〉闈㈣鍙栧苟灞曠ず `summary.totalPendingAmount` 绛夋柊澧炲瓧娈点��
+4. 楠岃瘉浠ヤ笅蹇嵎闂鍙ǔ瀹氳繑鍥炵粨鏋勫寲缁撴灉锛�
+   - 鏈湀閲囪喘閲戦鎺掑悕鍓嶅崄鐨勭墿鏂欐湁鍝簺锛�
+   - 鍝簺閲囪喘璁㈠崟杩樻湭鍏ュ簱锛�
+   - 鏈�杩�7澶╀緵搴斿晢鍒拌揣寮傚父鏈夊摢浜涳紵
+   - 甯垜缁熻寰呬粯娆鹃噰璐崟锛�
+   - 鍒楀嚭鏈湀閲囪喘閫�璐ф儏鍐�
diff --git "a/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md" "b/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..008660f
--- /dev/null
+++ "b/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
@@ -0,0 +1,113 @@
+# 棣栭〉 HomeController 鎺ュ彛鍗囩骇鍓嶇鍙樻洿鏂囨。
+
+鏇存柊鏃堕棿锛�2026-05-21  
+閫傜敤妯″潡锛氶椤碉紙`/home`锛�
+
+## 1. 鍙樻洿姒傝
+
+鏈涓� **鍏煎寮忓崌绾�**锛屾棫璋冪敤鏂瑰紡浠嶅彲鐢ㄣ��  
+閲嶇偣鏄粰鐢熶骇鐪嬫澘鎺ュ彛澧炲姞鏇存槑纭殑绛涢�夊弬鏁帮紝渚夸簬鍓嶇鎸夋棩鏈熷拰鐘舵�佹煡璇€��
+
+娑夊強鎺ュ彛锛�
+
+1. `GET /home/productionOrderProgress`
+2. `GET /home/todayProductionPlan`
+
+## 2. 鍙傛暟鍙樻洿
+
+### 2.1 鐢熶骇璁㈠崟杩涘害 `GET /home/productionOrderProgress`
+
+鏃у弬鏁帮紙浠嶅吋瀹癸級锛�
+
+- `tab`锛歚all` / `inProgress` / `completed` / `paused`
+- `pageNum`锛氶粯璁� `1`
+- `pageSize`锛氶粯璁� `10`锛屾渶澶� `50`
+
+鏂板鍙傛暟锛�
+
+- `status`锛堝彲閫夛級锛氱姸鎬佺瓫閫夛紝浼樺厛绾ч珮浜� `tab`  
+  鍙�夊�硷細`all` / `waiting` / `inProgress` / `completed` / `paused` / `1` / `2` / `3` / `4`
+- `bizDate`锛堝彲閫夛級锛氫笟鍔℃棩鏈熺瓫閫夛紝鏍煎紡 `yyyy-MM-dd`锛堟寜璁㈠崟鍒涘缓鏃堕棿杩囨护锛�
+
+鍙傛暟浼樺厛绾э細
+
+1. 濡傛灉浼犱簡 `status`锛屽悗绔紭鍏堟寜 `status` 瑙f瀽锛�
+2. 鏈紶 `status` 鏃讹紝娌跨敤鍘熸湁 `tab` 琛屼负锛�
+3. `status` 鎴� `bizDate` 鏍煎紡閿欒鏃惰繑鍥炲け璐ヤ俊鎭��
+
+璇锋眰绀轰緥锛�
+
+```http
+GET /home/productionOrderProgress?status=completed&bizDate=2026-05-20&pageNum=1&pageSize=10
+```
+
+### 2.2 浠婃棩鐢熶骇璁″垝 `GET /home/todayProductionPlan`
+
+鏃у弬鏁帮紙浠嶅吋瀹癸級锛�
+
+- `limit`锛氶粯璁� `4`锛屾渶澶� `20`
+
+鏂板鍙傛暟锛�
+
+- `planDate`锛堝彲閫夛級锛氳鍒掓棩鏈熺瓫閫夛紝鏍煎紡 `yyyy-MM-dd`锛堟寜 `plan_complete_time` 杩囨护锛�
+
+璇锋眰绀轰緥锛�
+
+```http
+GET /home/todayProductionPlan?limit=6&planDate=2026-05-21
+```
+
+## 3. 杩斿洖缁撴瀯鍙樻洿
+
+### 3.1 `productionOrderProgress` 杩斿洖鏂板瀛楁
+
+鏂板锛�
+
+- `status`锛氭爣鍑嗗寲鐘舵�佸洖鏄撅紙`all` / `waiting` / `inProgress` / `completed` / `paused`锛�
+- `bizDate`锛氭棩鏈熺瓫閫夊洖鏄撅紙鏈紶鏃朵负 `null`锛�
+- `waitingCount`锛氬緟寮�濮嬭鍗曟暟閲�
+
+鍏煎淇濈暀锛�
+
+- `tab` 瀛楁缁х画杩斿洖锛堣�侀〉闈㈡棤闇�鏀瑰姩鍙户缁娇鐢級
+
+杩斿洖绀轰緥锛�
+
+```json
+{
+  "tab": "completed",
+  "status": "completed",
+  "bizDate": "2026-05-20",
+  "total": 24,
+  "pageNum": 1,
+  "pageSize": 10,
+  "waitingCount": 3,
+  "inProgressCount": 6,
+  "completedCount": 12,
+  "pausedCount": 2,
+  "records": []
+}
+```
+
+### 3.2 `todayProductionPlan` 杩斿洖鏂板瀛楁
+
+鏂板锛�
+
+- `planDate`锛氭棩鏈熺瓫閫夊洖鏄撅紙鏈紶鏃朵负 `null`锛�
+
+杩斿洖绀轰緥锛�
+
+```json
+{
+  "planDate": "2026-05-21",
+  "total": 9,
+  "records": []
+}
+```
+
+## 4. 鍓嶇鏀归�犲缓璁�
+
+1. 鏂伴〉闈㈠缓璁紭鍏堜紶 `status`锛岄�愭鏇夸唬 `tab`銆�
+2. 闇�瑕佹寜鏃ユ湡澶嶇洏鐪嬫澘鏃讹紝浣跨敤 `bizDate` / `planDate`銆�
+3. 鑰侀〉闈㈠彲涓嶆敼锛岀户缁部鐢ㄥ師鍙傛暟涔熻兘姝e父鑱旇皟銆�
+
diff --git a/src/main/java/com/ruoyi/ai/assistant/ApproveTodoAgent.java b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoAgent.java
index 3b37909..bad0e0a 100644
--- a/src/main/java/com/ruoyi/ai/assistant/ApproveTodoAgent.java
+++ b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoAgent.java
@@ -3,6 +3,7 @@
 import dev.langchain4j.service.MemoryId;
 import dev.langchain4j.service.SystemMessage;
 import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
 import dev.langchain4j.service.spring.AiService;
 import reactor.core.publisher.Flux;
 
@@ -16,5 +17,5 @@
 public interface ApproveTodoAgent {
 
     @SystemMessage(fromResource = "approve-todo-agent-prompt.txt")
-    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage, @V("currentDate") String currentDate);
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/ManufacturingAgent.java b/src/main/java/com/ruoyi/ai/assistant/ManufacturingAgent.java
index f0e8cf7..0d16703 100644
--- a/src/main/java/com/ruoyi/ai/assistant/ManufacturingAgent.java
+++ b/src/main/java/com/ruoyi/ai/assistant/ManufacturingAgent.java
@@ -3,6 +3,7 @@
 import dev.langchain4j.service.MemoryId;
 import dev.langchain4j.service.SystemMessage;
 import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
 import dev.langchain4j.service.spring.AiService;
 import reactor.core.publisher.Flux;
 
@@ -17,5 +18,5 @@
 public interface ManufacturingAgent {
 
     @SystemMessage(fromResource = "manufacturing-agent-prompt.txt")
-    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage, @V("currentDate") String currentDate);
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/PurchaseAgent.java b/src/main/java/com/ruoyi/ai/assistant/PurchaseAgent.java
index 6a4ff4e..421261d 100644
--- a/src/main/java/com/ruoyi/ai/assistant/PurchaseAgent.java
+++ b/src/main/java/com/ruoyi/ai/assistant/PurchaseAgent.java
@@ -3,6 +3,7 @@
 import dev.langchain4j.service.MemoryId;
 import dev.langchain4j.service.SystemMessage;
 import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
 import dev.langchain4j.service.spring.AiService;
 import reactor.core.publisher.Flux;
 
@@ -17,5 +18,5 @@
 public interface PurchaseAgent {
 
     @SystemMessage(fromResource = "purchase-agent-prompt.txt")
-    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage, @V("currentDate") String currentDate);
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
index 5991fc3..c04915e 100644
--- a/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
+++ b/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
@@ -4,6 +4,9 @@
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -11,8 +14,12 @@
 public class PurchaseIntentExecutor {
 
     private static final Pattern ID_PATTERN = Pattern.compile("\\b\\d{1,12}\\b");
-    private static final Pattern LIMIT_PATTERN = Pattern.compile("(鍓峾鏈�杩�)?(\\d{1,2})鏉�");
-    private static final Pattern DATE_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
+    private static final Pattern LIMIT_PATTERN = Pattern.compile("(鍓峾鏈�杩�)?\\s*(\\d{1,2})\\s*鏉�");
+    private static final Pattern DATE_PATTERN = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})");
+    private static final Pattern RELATIVE_RANGE_PATTERN = Pattern.compile("(杩憒鏈�杩�)\\s*(\\d{1,3})\\s*(澶﹟鍛▅涓湀|鏈坾骞�)");
+    private static final Pattern HALF_RANGE_PATTERN = Pattern.compile("(鏈�杩憒杩�)?鍗�(涓�)?(鏈坾骞�)");
+    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
 
     private final PurchaseAgentTools purchaseAgentTools;
 
@@ -25,71 +32,63 @@
             return null;
         }
         String text = message.trim();
+        String quickPromptResponse = tryExecuteQuickPrompt(memoryId, text);
+        if (StringUtils.hasText(quickPromptResponse)) {
+            return quickPromptResponse;
+        }
 
-        if (containsAny(text, "鎺掕", "鎺掑悕", "鍓嶅嚑", "鍓嶄簲", "鍓嶅崄") && containsAny(text, "鐗╂枡", "浜у搧", "鍘熸潗鏂�", "閲囪喘閲戦", "閲戦")) {
-            return purchaseAgentTools.rankPurchaseMaterials(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    text,
-                    extractLimit(text)
-            );
+        String keyword = extractKeyword(text);
+        Integer limit = extractLimit(text);
+        DateRange dateRange = extractDateRange(text);
+        String startDate = dateRange.startDate();
+        String endDate = dateRange.endDate();
+
+        if (containsAny(text, "鎺掕", "鎺掑悕", "鍓嶅嚑", "鍓嶄簲", "鍓嶅崄")
+                && containsAny(text, "鐗╂枡", "浜у搧", "鍘熸潗鏂�", "閲囪喘閲戦", "閲戦")) {
+            return purchaseAgentTools.rankPurchaseMaterials(memoryId, startDate, endDate, text, limit);
         }
         if (containsAny(text, "鏈叆搴�", "寰呭叆搴�", "娌℃湁鍏ュ簱", "杩樻湭鍏ュ簱")) {
-            return purchaseAgentTools.listUnstockedPurchaseOrders(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractKeyword(text),
-                    extractLimit(text)
-            );
+            return purchaseAgentTools.listUnstockedPurchaseOrders(memoryId, startDate, endDate, keyword, limit);
         }
         if (containsAny(text, "鍒拌揣寮傚父", "鍒拌揣鏈夊紓甯�", "寮傚父鍒拌揣", "鍒拌揣闂", "渚涘簲鍟嗗埌璐у紓甯�")) {
-            return purchaseAgentTools.listArrivalExceptions(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    text,
-                    extractLimit(text)
-            );
+            return purchaseAgentTools.listArrivalExceptions(memoryId, startDate, endDate, text, limit);
         }
         if (containsAny(text, "寰呬粯娆�", "鏈粯娆�", "鏈粯娓�", "寰呮敮浠�", "搴斾粯")) {
-            return purchaseAgentTools.listPendingPaymentOrders(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractKeyword(text),
-                    extractLimit(text)
-            );
+            return purchaseAgentTools.listPendingPaymentOrders(memoryId, startDate, endDate, keyword, limit);
         }
         if (containsAny(text, "閫�璐�", "閫�鏂�", "鎷掓敹")) {
-            return purchaseAgentTools.listPurchaseReturns(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractKeyword(text),
-                    extractLimit(text)
-            );
+            return purchaseAgentTools.listPurchaseReturns(memoryId, startDate, endDate, keyword, limit);
         }
         if (isStatsIntent(text)) {
-            return purchaseAgentTools.getPurchaseStats(
-                    memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    text
-            );
+            return purchaseAgentTools.getPurchaseStats(memoryId, startDate, endDate, text);
         }
-        if (containsAny(text, "璇︽儏", "鏄庣粏") && extractId(text) != null) {
-            return purchaseAgentTools.getPurchaseLedgerDetail(memoryId, extractId(text));
+
+        Long ledgerId = extractId(text);
+        if (containsAny(text, "璇︽儏", "鏄庣粏") && ledgerId != null) {
+            return purchaseAgentTools.getPurchaseLedgerDetail(memoryId, ledgerId);
         }
         if (containsAny(text, "鍙拌处", "閲囪喘鍗�", "閲囪喘璁㈠崟", "璁㈠崟", "鍚堝悓", "鍒楄〃", "鏌ヨ")) {
-            return purchaseAgentTools.listPurchaseLedgers(
-                    memoryId,
-                    extractKeyword(text),
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractLimit(text)
-            );
+            return purchaseAgentTools.listPurchaseLedgers(memoryId, keyword, startDate, endDate, limit);
+        }
+        return null;
+    }
+
+    private String tryExecuteQuickPrompt(String memoryId, String text) {
+        String normalized = normalizeForMatch(text);
+        if ("鏈湀閲囪喘閲戦鎺掑悕鍓嶅崄鐨勭墿鏂欐湁鍝簺".equals(normalized)) {
+            return purchaseAgentTools.rankPurchaseMaterials(memoryId, null, null, "鏈湀", 10);
+        }
+        if ("鍝簺閲囪喘璁㈠崟杩樻湭鍏ュ簱".equals(normalized)) {
+            return purchaseAgentTools.listUnstockedPurchaseOrders(memoryId, null, null, null, 10);
+        }
+        if ("鏈�杩�7澶╀緵搴斿晢鍒拌揣寮傚父鏈夊摢浜�".equals(normalized)) {
+            return purchaseAgentTools.listArrivalExceptions(memoryId, null, null, "鏈�杩�7澶�", 10);
+        }
+        if ("甯垜缁熻寰呬粯娆鹃噰璐崟".equals(normalized)) {
+            return purchaseAgentTools.listPendingPaymentOrders(memoryId, null, null, null, 10);
+        }
+        if ("鍒楀嚭鏈湀閲囪喘閫�璐ф儏鍐�".equals(normalized)) {
+            return purchaseAgentTools.listPurchaseReturns(memoryId, null, null, null, 10);
         }
         return null;
     }
@@ -100,8 +99,10 @@
         }
         boolean queryWord = containsAny(text, "鏌ヨ", "鏌ョ湅", "鐪嬩笅", "鐪嬬湅", "鑾峰彇");
         boolean dataWord = containsAny(text, "鏁版嵁", "閲戦", "鏁伴噺", "鍚堝悓棰�", "浠樻棰�", "鍙戠エ棰�");
-        boolean timeWord = containsAny(text, "浠婂ぉ", "鏈懆", "鏈湀", "涓婃湀", "浠婂勾", "鍘诲勾", "杩戝崐骞�", "鏈�杩戝崐涓湀", "鍗婁釜鏈�")
-                || DATE_PATTERN.matcher(text).find();
+        boolean timeWord = containsAny(text, "浠婂ぉ", "鏄ㄥぉ", "鏈懆", "涓婂懆", "鏈湀", "涓婃湀", "浠婂勾", "鍘诲勾", "杩戝崐骞�", "鏈�杩戝崐涓湀", "鍗婁釜鏈�")
+                || DATE_PATTERN.matcher(text).find()
+                || RELATIVE_RANGE_PATTERN.matcher(text).find()
+                || HALF_RANGE_PATTERN.matcher(text).find();
         return queryWord && dataWord && timeWord;
     }
 
@@ -127,23 +128,125 @@
         return matcher.find() ? Integer.parseInt(matcher.group(2)) : 10;
     }
 
-    private String extractStartDate(String text) {
+    private DateRange extractDateRange(String text) {
         Matcher matcher = DATE_PATTERN.matcher(text);
-        return matcher.find() ? matcher.group() : null;
+        if (matcher.find()) {
+            String first = matcher.group(1);
+            String second = matcher.find() ? matcher.group(1) : first;
+            return buildDateRange(first, second);
+        }
+
+        LocalDate today = LocalDate.now(CHINA_ZONE_ID);
+        if (text.contains("浠婂ぉ")) {
+            return new DateRange(formatDate(today), formatDate(today));
+        }
+        if (text.contains("鏄ㄥぉ")) {
+            LocalDate yesterday = today.minusDays(1);
+            return new DateRange(formatDate(yesterday), formatDate(yesterday));
+        }
+        if (text.contains("鏈懆")) {
+            LocalDate start = today.minusDays(today.getDayOfWeek().getValue() - 1L);
+            return new DateRange(formatDate(start), formatDate(today));
+        }
+        if (text.contains("涓婂懆")) {
+            LocalDate thisWeekStart = today.minusDays(today.getDayOfWeek().getValue() - 1L);
+            LocalDate start = thisWeekStart.minusWeeks(1);
+            LocalDate end = start.plusDays(6);
+            return new DateRange(formatDate(start), formatDate(end));
+        }
+        if (text.contains("鏈湀")) {
+            return new DateRange(formatDate(today.withDayOfMonth(1)), formatDate(today));
+        }
+        if (text.contains("涓婃湀")) {
+            LocalDate start = today.minusMonths(1).withDayOfMonth(1);
+            return new DateRange(formatDate(start), formatDate(start.withDayOfMonth(start.lengthOfMonth())));
+        }
+        if (text.contains("浠婂勾") || text.contains("鏈勾")) {
+            return new DateRange(formatDate(today.withDayOfYear(1)), formatDate(today));
+        }
+        if (text.contains("鍘诲勾")) {
+            LocalDate start = today.minusYears(1).withDayOfYear(1);
+            LocalDate end = start.withDayOfYear(start.lengthOfYear());
+            return new DateRange(formatDate(start), formatDate(end));
+        }
+        if (containsAny(text, "杩戝崐骞�", "鏈�杩戝崐骞�")) {
+            return new DateRange(formatDate(today.minusMonths(6).plusDays(1)), formatDate(today));
+        }
+        if (containsAny(text, "杩戝崐涓湀", "鏈�杩戝崐涓湀", "鍗婁釜鏈�")) {
+            return new DateRange(formatDate(today.minusDays(14)), formatDate(today));
+        }
+
+        Matcher relativeMatcher = RELATIVE_RANGE_PATTERN.matcher(text);
+        if (relativeMatcher.find()) {
+            int amount = Integer.parseInt(relativeMatcher.group(2));
+            String unit = relativeMatcher.group(3);
+            LocalDate start = switch (unit) {
+                case "澶�" -> today.minusDays(Math.max(amount - 1L, 0));
+                case "鍛�" -> today.minusWeeks(Math.max(amount, 1)).plusDays(1);
+                case "涓湀", "鏈�" -> today.minusMonths(Math.max(amount, 1)).plusDays(1);
+                case "骞�" -> today.minusYears(Math.max(amount, 1)).plusDays(1);
+                default -> today.minusDays(29);
+            };
+            return new DateRange(formatDate(start), formatDate(today));
+        }
+
+        return new DateRange(null, null);
     }
 
-    private String extractEndDate(String text) {
-        Matcher matcher = DATE_PATTERN.matcher(text);
-        if (!matcher.find()) {
+    private DateRange buildDateRange(String start, String end) {
+        LocalDate startDate = parseDate(start);
+        LocalDate endDate = parseDate(end);
+        if (startDate == null || endDate == null) {
+            return new DateRange(null, null);
+        }
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+        return new DateRange(formatDate(startDate), formatDate(endDate));
+    }
+
+    private LocalDate parseDate(String text) {
+        try {
+            return LocalDate.parse(text, DATE_FMT);
+        } catch (Exception ignored) {
             return null;
         }
-        return matcher.find() ? matcher.group() : null;
+    }
+
+    private String formatDate(LocalDate date) {
+        return date == null ? null : date.format(DATE_FMT);
+    }
+
+    private String normalizeForMatch(String text) {
+        if (!StringUtils.hasText(text)) {
+            return "";
+        }
+        return text.replace("锛�", "")
+                .replace(",", "")
+                .replace("銆�", "")
+                .replace(".", "")
+                .replace("锛�", "")
+                .replace("!", "")
+                .replace("锛�", "")
+                .replace("?", "")
+                .replace("锛�", "")
+                .replace(":", "")
+                .replace("锛�", "")
+                .replace(";", "")
+                .replace(" ", "")
+                .trim();
     }
 
     private String extractKeyword(String text) {
         String cleaned = text
                 .replace("鏌ヨ", "")
                 .replace("鏌ョ湅", "")
+                .replace("鐪嬩笅", "")
+                .replace("鐪嬬湅", "")
+                .replace("璇�", "")
+                .replace("涓�涓�", "")
                 .replace("閲囪喘", "")
                 .replace("閲囪喘鍗�", "")
                 .replace("閲囪喘璁㈠崟", "")
@@ -153,9 +256,33 @@
                 .replace("鍝簺", "")
                 .replace("鍒楀嚭", "")
                 .replace("甯垜", "")
+                .replace("缁熻", "")
+                .replace("鍒嗘瀽", "")
+                .replace("鏈湀", "")
+                .replace("涓婃湀", "")
+                .replace("鏈勾", "")
+                .replace("浠婂勾", "")
+                .replace("鍘诲勾", "")
+                .replace("鏈懆", "")
+                .replace("涓婂懆", "")
+                .replace("浠婂ぉ", "")
+                .replace("鏄ㄥぉ", "")
+                .replace("杩�30澶�", "")
+                .replace("杩�7澶�", "")
+                .replace("杩�15澶�", "")
+                .replace("杩�60澶�", "")
+                .replace("鏈�杩�30澶�", "")
+                .replace("鏈�杩�7澶�", "")
+                .replace("鏈�杩�15澶�", "")
+                .replace("鏈�杩�60澶�", "")
                 .replace("鏈�杩�10鏉�", "")
                 .replace("鍓�10鏉�", "")
+                .replace("鍓�20鏉�", "")
+                .replace("鏈�杩�20鏉�", "")
                 .trim();
         return cleaned.length() >= 2 ? cleaned : null;
     }
+
+    private record DateRange(String startDate, String endDate) {
+    }
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/SalesAgent.java b/src/main/java/com/ruoyi/ai/assistant/SalesAgent.java
index 1636239..e2f9a81 100644
--- a/src/main/java/com/ruoyi/ai/assistant/SalesAgent.java
+++ b/src/main/java/com/ruoyi/ai/assistant/SalesAgent.java
@@ -3,6 +3,7 @@
 import dev.langchain4j.service.MemoryId;
 import dev.langchain4j.service.SystemMessage;
 import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
 import dev.langchain4j.service.spring.AiService;
 import reactor.core.publisher.Flux;
 
@@ -17,6 +18,5 @@
 public interface SalesAgent {
 
     @SystemMessage(fromResource = "sales-agent-prompt.txt")
-    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
+    Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage, @V("currentDate") String currentDate);
 }
-
diff --git a/src/main/java/com/ruoyi/ai/controller/ManufacturingAiController.java b/src/main/java/com/ruoyi/ai/controller/ManufacturingAiController.java
index cb7c0ba..87eb418 100644
--- a/src/main/java/com/ruoyi/ai/controller/ManufacturingAiController.java
+++ b/src/main/java/com/ruoyi/ai/controller/ManufacturingAiController.java
@@ -24,12 +24,18 @@
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Flux;
 
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 @Tag(name = "鍒堕�犳櫤鑳藉姪鎵�")
 @RestController
 @RequestMapping("/manufacturing-ai")
 public class ManufacturingAiController extends BaseController {
+
+    private static final DateTimeFormatter CURRENT_DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
 
     private final ManufacturingAgent manufacturingAgent;
     private final ManufacturingIntentExecutor manufacturingIntentExecutor;
@@ -76,7 +82,7 @@
             return Flux.just(directResponse);
         }
 
-        return manufacturingAgent.chat(memoryId, userMessage)
+        return manufacturingAgent.chat(memoryId, userMessage, currentDateForPrompt())
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(memoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(memoryId, loginUser));
     }
@@ -99,4 +105,8 @@
         aiSessionUserContext.remove(memoryId);
         return toAjax(aiChatSessionService.deleteCurrentUserSession(memoryId, SecurityUtils.getLoginUser()));
     }
+
+    private String currentDateForPrompt() {
+        return LocalDate.now(CHINA_ZONE_ID).format(CURRENT_DATE_FMT);
+    }
 }
diff --git a/src/main/java/com/ruoyi/ai/controller/SalesAiController.java b/src/main/java/com/ruoyi/ai/controller/SalesAiController.java
index c3a569b..0c92ad6 100644
--- a/src/main/java/com/ruoyi/ai/controller/SalesAiController.java
+++ b/src/main/java/com/ruoyi/ai/controller/SalesAiController.java
@@ -24,12 +24,18 @@
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Flux;
 
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 @Tag(name = "閿�鍞姪鎵嬫櫤鑳戒綋")
 @RestController
 @RequestMapping("/sales-ai")
 public class SalesAiController extends BaseController {
+
+    private static final DateTimeFormatter CURRENT_DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
 
     private final SalesAgent salesAgent;
     private final SalesIntentExecutor salesIntentExecutor;
@@ -86,7 +92,7 @@
             return Flux.just(noGuessResponse);
         }
 
-        return salesAgent.chat(memoryId, userMessage)
+        return salesAgent.chat(memoryId, userMessage, currentDateForPrompt())
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(memoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(memoryId, loginUser));
     }
@@ -128,4 +134,8 @@
         }
         return false;
     }
+
+    private String currentDateForPrompt() {
+        return LocalDate.now(CHINA_ZONE_ID).format(CURRENT_DATE_FMT);
+    }
 }
diff --git a/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java b/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
index affa347..82d088c 100644
--- a/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
+++ b/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
@@ -29,6 +29,9 @@
 import reactor.core.publisher.Flux;
 
 import java.io.IOException;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.UUID;
@@ -39,6 +42,8 @@
 public class XiaozhiController extends BaseController {
 
     private static final String FILE_ANALYZE_MEMORY_PREFIX = "file-analyze::";
+    private static final DateTimeFormatter CURRENT_DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
 
     private final ApproveTodoAgent approveTodoAgent;
     private final ApproveTodoIntentExecutor approveTodoIntentExecutor;
@@ -100,7 +105,7 @@
             return Flux.just(noGuessResponse);
         }
 
-        return approveTodoAgent.chat(memoryId, userMessage)
+        return approveTodoAgent.chat(memoryId, userMessage, currentDateForPrompt())
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(memoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(memoryId, loginUser));
     }
@@ -190,4 +195,8 @@
         }
         return false;
     }
+
+    private String currentDateForPrompt() {
+        return LocalDate.now(CHINA_ZONE_ID).format(CURRENT_DATE_FMT);
+    }
 }
diff --git a/src/main/java/com/ruoyi/ai/service/PurchaseAiService.java b/src/main/java/com/ruoyi/ai/service/PurchaseAiService.java
index 47c914b..cbc936c 100644
--- a/src/main/java/com/ruoyi/ai/service/PurchaseAiService.java
+++ b/src/main/java/com/ruoyi/ai/service/PurchaseAiService.java
@@ -1,5 +1,6 @@
 package com.ruoyi.ai.service;
 
+import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -68,6 +69,8 @@
     private static final int MAX_FILE_COUNT = 10;
     private static final int MAX_SINGLE_FILE_TEXT_LENGTH = 8000;
     private static final int MAX_TOTAL_FILE_TEXT_LENGTH = 30000;
+    private static final DateTimeFormatter CURRENT_DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
 
     private final PurchaseAgent purchaseAgent;
     private final PurchaseIntentExecutor purchaseIntentExecutor;
@@ -132,7 +135,17 @@
             return Flux.just(directResponse);
         }
 
-        return purchaseAgent.chat(memoryId, userMessage)
+        if (isPurchaseBusinessIntent(userMessage)) {
+            String noGuessResponse = buildNoGuessResponse();
+            mongoChatMemoryStore.appendMessages(
+                    memoryId,
+                    List.of(UserMessage.from(userMessage), AiMessage.from(noGuessResponse))
+            );
+            aiChatSessionService.refreshSessionStats(memoryId, loginUser);
+            return Flux.just(noGuessResponse);
+        }
+
+        return purchaseAgent.chat(memoryId, userMessage, currentDateForPrompt())
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(memoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(memoryId, loginUser));
     }
@@ -194,10 +207,10 @@
                     .doOnError(ex -> aiChatSessionService.refreshSessionStats(finalMemoryId, loginUser));
         }
 
-        return Flux.defer(() -> purchaseAgent.chat(finalMemoryId, userPrompt))
+        return Flux.defer(() -> purchaseAgent.chat(finalMemoryId, userPrompt, currentDateForPrompt()))
                 .onErrorResume(NoSuchElementException.class, ex -> {
                     mongoChatMemoryStore.deleteMessages(finalMemoryId);
-                    return purchaseAgent.chat(finalMemoryId, userPrompt);
+                    return purchaseAgent.chat(finalMemoryId, userPrompt, currentDateForPrompt());
                 })
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(finalMemoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(finalMemoryId, loginUser));
@@ -464,6 +477,51 @@
         };
     }
 
+    private String currentDateForPrompt() {
+        return LocalDate.now(CHINA_ZONE_ID).format(CURRENT_DATE_FMT);
+    }
+
+    private boolean isPurchaseBusinessIntent(String message) {
+        if (!StringUtils.hasText(message)) {
+            return false;
+        }
+        String text = message.trim();
+        boolean hasDomainWord = containsAny(text,
+                "閲囪喘", "閲囪喘鍙拌处", "閲囪喘鍗�", "閲囪喘璁㈠崟", "渚涘簲鍟�", "鐗╂枡", "鍏ュ簱", "鍒拌揣", "寰呬粯娆�",
+                "浠樻", "閫�璐�", "閫�鏂�", "鍙戠エ", "鍚堝悓");
+        boolean hasIntentWord = containsAny(text,
+                "鏌ヨ", "鏌ョ湅", "缁熻", "鍒嗘瀽", "鎺掕", "鎺掑悕", "鍒楀嚭", "鏈夊摢浜�", "鎯呭喌", "鏄庣粏", "璇︽儏", "鎶ヨ〃");
+        return hasDomainWord && hasIntentWord;
+    }
+
+    private boolean containsAny(String text, String... keywords) {
+        for (String keyword : keywords) {
+            if (text.contains(keyword)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String buildNoGuessResponse() {
+        Map<String, Object> result = new LinkedHashMap<>();
+        result.put("success", false);
+        result.put("type", "purchase_intent_not_recognized");
+        result.put("description", "鏈瘑鍒埌鍙墽琛岀殑閲囪喘鏌ヨ鏉′欢銆備负淇濊瘉缁撴灉鍑嗙‘锛屽綋鍓嶄笉浼氭帹娴嬫垨缂栭�犳暟鎹紝璇疯ˉ鍏呮槑纭椂闂磋寖鍥淬�佷緵搴斿晢銆侀噰璐悎鍚屽彿鎴栫墿鏂欏悗鍐嶆煡璇€��");
+        result.put("summary", Map.of());
+        result.put("data", Map.of(
+                "quickPrompts", List.of(
+                        "鏈湀閲囪喘閲戦鎺掑悕鍓嶅崄鐨勭墿鏂欐湁鍝簺锛�",
+                        "鍝簺閲囪喘璁㈠崟杩樻湭鍏ュ簱锛�",
+                        "鏈�杩�7澶╀緵搴斿晢鍒拌揣寮傚父鏈夊摢浜涳紵",
+                        "甯垜缁熻寰呬粯娆鹃噰璐崟锛�",
+                        "鍒楀嚭鏈湀閲囪喘閫�璐ф儏鍐�"
+                )
+        ));
+        result.put("charts", Map.of());
+        return JSON.toJSONString(result);
+    }
+
     private String buildPurchaseFileAnalyzePrompt(String message, String fileContent) {
         return """
                 浣犳槸閲囪喘涓氬姟鏂囦欢鍒嗘瀽鍔╂墜銆傝涓ユ牸鏍规嵁鐢ㄦ埛涓婁紶鐨勫涓枃浠跺拰鐢ㄦ埛瑕佹眰鎻愬彇閲囪喘涓氬姟鏁版嵁銆�
diff --git a/src/main/java/com/ruoyi/ai/tools/PurchaseAgentTools.java b/src/main/java/com/ruoyi/ai/tools/PurchaseAgentTools.java
index c25aeed..5d0f9ae 100644
--- a/src/main/java/com/ruoyi/ai/tools/PurchaseAgentTools.java
+++ b/src/main/java/com/ruoyi/ai/tools/PurchaseAgentTools.java
@@ -23,6 +23,7 @@
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
@@ -37,6 +38,7 @@
 public class PurchaseAgentTools {
 
     private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
     private static final int DEFAULT_LIMIT = 10;
     private static final int MAX_LIMIT = 30;
 
@@ -279,8 +281,24 @@
                 .sorted(Comparator.comparing(item -> (BigDecimal) item.get("pendingAmount"), Comparator.reverseOrder()))
                 .limit(normalizeLimit(limit))
                 .collect(Collectors.toList());
+
+        BigDecimal totalContractAmount = items.stream()
+                .map(item -> asBigDecimal(item.get("contractAmount")))
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalPaidAmount = items.stream()
+                .map(item -> asBigDecimal(item.get("paidAmount")))
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalPendingAmount = items.stream()
+                .map(item -> asBigDecimal(item.get("pendingAmount")))
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        Map<String, Object> summary = rangeSummary(range, items.size());
+        summary.put("pendingOrderCount", items.size());
+        summary.put("totalContractAmount", totalContractAmount);
+        summary.put("totalPaidAmount", totalPaidAmount);
+        summary.put("totalPendingAmount", totalPendingAmount);
+
         return jsonResponse(true, "purchase_pending_payment_list", "宸茶繑鍥炲緟浠樻閲囪喘鍗曘��",
-                rangeSummary(range, items.size()), Map.of("items", items), Map.of());
+                summary, Map.of("items", items), Map.of());
     }
 
     @Tool(name = "鏌ヨ閲囪喘閫�璐ф儏鍐�", value = "鎸夋椂闂磋寖鍥存煡璇㈤噰璐��璐у崟鍒楄〃鍜岄��璐ч噾棰濄��")
@@ -440,6 +458,26 @@
         return value == null ? BigDecimal.ZERO : value;
     }
 
+    private BigDecimal asBigDecimal(Object value) {
+        if (value == null) {
+            return BigDecimal.ZERO;
+        }
+        if (value instanceof BigDecimal decimal) {
+            return decimal;
+        }
+        if (value instanceof Number number) {
+            return new BigDecimal(String.valueOf(number));
+        }
+        return BigDecimal.ZERO;
+    }
+
+    private List<PaymentRegistration> queryPayments(LoginUser loginUser, DateRange range) {
+        LambdaQueryWrapper<PaymentRegistration> wrapper = new LambdaQueryWrapper<>();
+        applyTenantFilter(wrapper, loginUser.getTenantId(), PaymentRegistration::getTenantId);
+        wrapper.ge(PaymentRegistration::getPaymentDate, toDate(range.start()))
+                .lt(PaymentRegistration::getPaymentDate, toExclusiveEndDate(range.end()));
+        return defaultList(paymentRegistrationMapper.selectList(wrapper));
+    }
 
 
     private List<PurchaseReturnOrders> queryReturns(LoginUser loginUser, DateRange range) {
@@ -464,7 +502,7 @@
     }
 
     private DateRange resolveDateRange(String startDate, String endDate, String timeRange) {
-        LocalDate today = LocalDate.now();
+        LocalDate today = LocalDate.now(CHINA_ZONE_ID);
         LocalDate start = parseLocalDate(startDate);
         LocalDate end = parseLocalDate(endDate);
         if (start != null || end != null) {
@@ -481,6 +519,22 @@
             return new DateRange(today.minusDays(29), today, "杩�30澶�");
         }
         String text = timeRange.trim();
+        if (text.contains("浠婂ぉ")) {
+            return new DateRange(today, today, "浠婂ぉ");
+        }
+        if (text.contains("鏄ㄥぉ")) {
+            LocalDate yesterday = today.minusDays(1);
+            return new DateRange(yesterday, yesterday, "鏄ㄥぉ");
+        }
+        if (text.contains("鏈懆")) {
+            LocalDate startOfWeek = today.minusDays(today.getDayOfWeek().getValue() - 1L);
+            return new DateRange(startOfWeek, today, "鏈懆");
+        }
+        if (text.contains("涓婂懆")) {
+            LocalDate thisWeekStart = today.minusDays(today.getDayOfWeek().getValue() - 1L);
+            LocalDate startOfLastWeek = thisWeekStart.minusWeeks(1);
+            return new DateRange(startOfLastWeek, startOfLastWeek.plusDays(6), "涓婂懆");
+        }
         if (text.contains("浠婂勾") || text.contains("鏈勾")) {
             return new DateRange(today.withDayOfYear(1), today, "浠婂勾");
         }
@@ -518,7 +572,11 @@
         if (!StringUtils.hasText(text)) {
             return null;
         }
-        return LocalDate.parse(text.trim(), DATE_FMT);
+        try {
+            return LocalDate.parse(text.trim(), DATE_FMT);
+        } catch (Exception ignored) {
+            return null;
+        }
     }
 
     private Date toDate(LocalDate localDate) {
diff --git a/src/main/java/com/ruoyi/home/controller/HomeController.java b/src/main/java/com/ruoyi/home/controller/HomeController.java
index 2b3bb32..7878d28 100644
--- a/src/main/java/com/ruoyi/home/controller/HomeController.java
+++ b/src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -16,8 +16,8 @@
 import com.ruoyi.production.mapper.ProductionOrderMapper;
 import com.ruoyi.production.mapper.ProductionProductOutputMapper;
 import com.ruoyi.production.pojo.ProductionOrder;
-import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Operation;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,8 +28,16 @@
 import java.math.RoundingMode;
 import java.text.ParseException;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.*;
 
 /**
@@ -40,7 +48,7 @@
 @Tag(name = "棣栭〉缁熻")
 @RequestMapping("/home")
 @AllArgsConstructor
-    public class HomeController extends BaseController {
+public class HomeController extends BaseController {
 
     private final HomeService homeService;
     private final ProductionOrderMapper productionOrderMapper;
@@ -49,6 +57,7 @@
     private final DeviceRepairMapper deviceRepairMapper;
 
     private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
     private static final Integer ORDER_STATUS_WAIT = 1;
     private static final Integer ORDER_STATUS_RUNNING = 2;
     private static final Integer ORDER_STATUS_COMPLETED = 3;
@@ -58,7 +67,7 @@
     @GetMapping("/todos")
     @Log(title = "寰呭姙浜嬮」", businessType = BusinessType.OTHER)
     @Operation(summary = "寰呭姙浜嬮」")
-    public R todos(ApproveProcess req) throws ParseException {
+    public R todos() throws ParseException {
         List<ApproveProcess> approveProcessList = homeService.todos();
         return R.ok(approveProcessList);
     }
@@ -130,7 +139,7 @@
     @GetMapping("/business")
     @Log(title = "閿�鍞�-閲囪喘-搴撳瓨鏁版嵁", businessType = BusinessType.OTHER)
     @Operation(summary = "閿�鍞�-閲囪喘-搴撳瓨鏁版嵁")
-    public R business(HomeBusinessDto req) {
+    public R business() {
         HomeBusinessDto homeBusinessDto = homeService.business();
         return R.ok(homeBusinessDto);
     }
@@ -138,7 +147,7 @@
     @GetMapping("/analysisCustomerContractAmounts")
     @Log(title = "瀹㈡埛鍚堝悓閲戦鍒嗘瀽", businessType = BusinessType.OTHER)
     @Operation(summary = "瀹㈡埛鍚堝悓閲戦鍒嗘瀽")
-    public R analysisCustomerContractAmounts(AnalysisCustomerContractAmountsDto req) {
+    public R analysisCustomerContractAmounts() {
         AnalysisCustomerContractAmountsDto analysisCustomerContractAmounts = homeService.analysisCustomerContractAmounts();
         return R.ok(analysisCustomerContractAmounts);
     }
@@ -241,13 +250,27 @@
     @GetMapping("/productionOrderProgress")
     @Operation(summary = "Production Order Progress")
     public R productionOrderProgress(@RequestParam(defaultValue = "all") String tab,
-                                              @RequestParam(defaultValue = "1") Long pageNum,
-                                              @RequestParam(defaultValue = "10") Long pageSize) {
+                                     @RequestParam(required = false) String status,
+                                     @RequestParam(required = false) String bizDate,
+                                     @RequestParam(defaultValue = "1") Long pageNum,
+                                     @RequestParam(defaultValue = "10") Long pageSize) {
+        LocalDate queryDate = parseDateOrNull(bizDate);
+        if (!isBlank(bizDate) && queryDate == null) {
+            return R.fail("bizDate鏍煎紡閿欒锛岃浣跨敤yyyy-MM-dd");
+        }
+        Integer statusFromParam = parseOrderStatus(status);
+        if (!isBlank(status) && statusFromParam == null && !"all".equalsIgnoreCase(status.trim())) {
+            return R.fail("status鍙傛暟涓嶅悎娉曪紝鍙�夊�硷細all/waiting/inProgress/completed/paused 鎴� 1/2/3/4");
+        }
+        Integer queryStatus = resolveOrderStatus(status, tab);
+
         long safePageNum = pageNum == null || pageNum < 1 ? 1 : pageNum;
         long safePageSize = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50);
-        Integer status = resolveOrderStatus(tab);
         long offset = (safePageNum - 1) * safePageSize;
-        List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeOrderProgressPage(status, offset, safePageSize);
+        LocalDateTime startTime = queryDate == null ? null : queryDate.atStartOfDay();
+        LocalDateTime endTime = queryDate == null ? null : queryDate.plusDays(1).atStartOfDay();
+
+        List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeOrderProgressPage(queryStatus, offset, safePageSize, startTime, endTime);
         List<Map<String, Object>> records = new ArrayList<>();
         if (rawRows != null) {
             for (Map<String, Object> rawRow : rawRows) {
@@ -255,15 +278,18 @@
             }
         }
 
+        long waitingCount = 0L;
         long inProgressCount = 0L;
         long completedCount = 0L;
         long pausedCount = 0L;
-        List<Map<String, Object>> statusCountRows = productionOrderMapper.countHomeOrderProgressByStatus();
+        List<Map<String, Object>> statusCountRows = productionOrderMapper.countHomeOrderProgressByStatus(startTime, endTime);
         if (statusCountRows != null) {
             for (Map<String, Object> countRow : statusCountRows) {
                 Integer statusKey = toInteger(countRow.get("status"));
                 long cnt = toLong(countRow.get("cnt"));
-                if (Objects.equals(statusKey, ORDER_STATUS_RUNNING)) {
+                if (Objects.equals(statusKey, ORDER_STATUS_WAIT)) {
+                    waitingCount = cnt;
+                } else if (Objects.equals(statusKey, ORDER_STATUS_RUNNING)) {
                     inProgressCount = cnt;
                 } else if (Objects.equals(statusKey, ORDER_STATUS_COMPLETED)) {
                     completedCount = cnt;
@@ -274,10 +300,13 @@
         }
 
         Map<String, Object> result = new LinkedHashMap<>();
-        result.put("tab", tab);
-        result.put("total", toLong(productionOrderMapper.countHomeOrderProgress(status)));
+        result.put("tab", mapOrderTab(queryStatus));
+        result.put("status", mapOrderStatus(queryStatus));
+        result.put("bizDate", queryDate == null ? null : queryDate.format(DATE_FORMATTER));
+        result.put("total", toLong(productionOrderMapper.countHomeOrderProgress(queryStatus, startTime, endTime)));
         result.put("pageNum", safePageNum);
         result.put("pageSize", safePageSize);
+        result.put("waitingCount", waitingCount);
         result.put("inProgressCount", inProgressCount);
         result.put("completedCount", completedCount);
         result.put("pausedCount", pausedCount);
@@ -287,10 +316,18 @@
 
     @GetMapping("/todayProductionPlan")
     @Operation(summary = "Today Production Plan")
-    public R todayProductionPlan(@RequestParam(defaultValue = "4") Long limit) {
+    public R todayProductionPlan(@RequestParam(defaultValue = "4") Long limit,
+                                 @RequestParam(required = false) String planDate) {
+        LocalDate queryDate = parseDateOrNull(planDate);
+        if (!isBlank(planDate) && queryDate == null) {
+            return R.fail("planDate鏍煎紡閿欒锛岃浣跨敤yyyy-MM-dd");
+        }
+
         long safeLimit = limit == null || limit < 1 ? 4 : Math.min(limit, 20);
+        LocalDateTime planStart = queryDate == null ? null : queryDate.atStartOfDay();
+        LocalDateTime planEnd = queryDate == null ? null : queryDate.plusDays(1).atStartOfDay();
         List<Map<String, Object>> records = new ArrayList<>();
-        List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeTodayProductionPlan(safeLimit);
+        List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeTodayProductionPlan(safeLimit, planStart, planEnd);
         if (rawRows != null) {
             for (Map<String, Object> rawRow : rawRows) {
                 Map<String, Object> row = new LinkedHashMap<>();
@@ -306,7 +343,8 @@
         }
 
         Map<String, Object> result = new LinkedHashMap<>();
-        result.put("total", toLong(productionOrderMapper.countHomeTodayProductionPlan()));
+        result.put("planDate", queryDate == null ? null : queryDate.format(DATE_FORMATTER));
+        result.put("total", toLong(productionOrderMapper.countHomeTodayProductionPlan(planStart, planEnd)));
         result.put("records", records);
         return R.ok(result);
     }
@@ -367,7 +405,7 @@
     @GetMapping("/qualityStatistics")
     @Log(title = "璐ㄩ噺鍒嗘瀽", businessType = BusinessType.OTHER)
     @Operation(summary = "璐ㄩ噺鍒嗘瀽")
-    public R qualityStatistics(QualityStatisticsDto req) {
+    public R qualityStatistics() {
         QualityStatisticsDto qualityStatisticsDto = homeService.qualityStatistics();
         return R.ok(qualityStatisticsDto);
     }
@@ -418,7 +456,7 @@
     @GetMapping("/statisticsReceivablePayable")
     @Log(title = "搴旀敹搴斾粯缁熻", businessType = BusinessType.OTHER)
     @Operation(summary = "搴旀敹搴斾粯缁熻")
-    public R statisticsReceivablePayable(StatisticsReceivablePayableDto req, @DefaultType Integer type ) {
+    public R statisticsReceivablePayable(@DefaultType Integer type ) {
         StatisticsReceivablePayableDto statisticsReceivablePayable = homeService.statisticsReceivablePayable(type);
         return R.ok(statisticsReceivablePayable);
     }
@@ -467,21 +505,66 @@
         return row;
     }
 
-    private Integer resolveOrderStatus(String tab) {
-        if (tab == null) {
+    private Integer resolveOrderStatus(String status, String tab) {
+        if (!isBlank(status)) {
+            return parseOrderStatus(status);
+        }
+        return parseOrderStatus(tab);
+    }
+
+    private Integer parseOrderStatus(String rawStatus) {
+        if (isBlank(rawStatus)) {
             return null;
         }
-        String normalized = tab.trim().toLowerCase();
-        if ("inprogress".equals(normalized)) {
+        String normalized = rawStatus.trim().toLowerCase();
+        if ("all".equals(normalized)) {
+            return null;
+        }
+        if ("1".equals(normalized) || "waiting".equals(normalized) || "wait".equals(normalized)) {
+            return ORDER_STATUS_WAIT;
+        }
+        if ("2".equals(normalized) || "inprogress".equals(normalized) || "running".equals(normalized)) {
             return ORDER_STATUS_RUNNING;
         }
-        if ("completed".equals(normalized)) {
+        if ("3".equals(normalized) || "completed".equals(normalized)) {
             return ORDER_STATUS_COMPLETED;
         }
-        if ("paused".equals(normalized)) {
+        if ("4".equals(normalized) || "paused".equals(normalized)) {
             return ORDER_STATUS_PAUSED;
         }
         return null;
+    }
+
+    private String mapOrderTab(Integer status) {
+        if (Objects.equals(status, ORDER_STATUS_RUNNING)) {
+            return "inProgress";
+        }
+        if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
+            return "completed";
+        }
+        if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
+            return "paused";
+        }
+        if (Objects.equals(status, ORDER_STATUS_WAIT)) {
+            return "waiting";
+        }
+        return "all";
+    }
+
+    private String mapOrderStatus(Integer status) {
+        if (Objects.equals(status, ORDER_STATUS_WAIT)) {
+            return "waiting";
+        }
+        if (Objects.equals(status, ORDER_STATUS_RUNNING)) {
+            return "inProgress";
+        }
+        if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
+            return "completed";
+        }
+        if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
+            return "paused";
+        }
+        return "all";
     }
 
     private String mapOrderStatusLabel(Integer status) {
@@ -639,6 +722,21 @@
         }
     }
 
+    private LocalDate parseDateOrNull(String rawDate) {
+        if (isBlank(rawDate)) {
+            return null;
+        }
+        try {
+            return LocalDate.parse(rawDate.trim(), DATE_FORMATTER);
+        } catch (DateTimeParseException ex) {
+            return null;
+        }
+    }
+
+    private boolean isBlank(String value) {
+        return value == null || value.trim().isEmpty();
+    }
+
     private BigDecimal zeroIfNull(BigDecimal value) {
         return value == null ? BigDecimal.ZERO : value;
     }
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
index 965cbf3..8a75dcd 100644
--- a/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
@@ -44,4 +44,7 @@
     @Schema(description = "缁撴潫鏃ユ湡")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate endDate;
+
+    @Schema(description = "鏄惁鐢熶骇")
+    private Integer isProduction;
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
index dda1aa0..2765c10 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
@@ -39,7 +39,7 @@
     @PostMapping("/updateRouteItem")
     @Operation(summary = "淇敼鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
     public R updateRouteItem(@RequestBody ProductionOrderRoutingOperation productionOrderRoutingOperation) {
-        return R.ok(productionOrderRoutingOperationService.updateById(productionOrderRoutingOperation));
+        return R.ok(productionOrderRoutingOperationService.updateRouteItem(productionOrderRoutingOperation));
     }
 
     @DeleteMapping("/deleteRouteItem/{id}")
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
index fcc9172..cec7ca5 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
@@ -42,14 +42,22 @@
 
     List<Map<String, Object>> selectHomeOrderProgressPage(@Param("status") Integer status,
                                                           @Param("offset") Long offset,
-                                                          @Param("size") Long size);
+                                                          @Param("size") Long size,
+                                                          @Param("startTime") LocalDateTime startTime,
+                                                          @Param("endTime") LocalDateTime endTime);
 
-    Long countHomeOrderProgress(@Param("status") Integer status);
+    Long countHomeOrderProgress(@Param("status") Integer status,
+                                @Param("startTime") LocalDateTime startTime,
+                                @Param("endTime") LocalDateTime endTime);
 
-    List<Map<String, Object>> countHomeOrderProgressByStatus();
+    List<Map<String, Object>> countHomeOrderProgressByStatus(@Param("startTime") LocalDateTime startTime,
+                                                              @Param("endTime") LocalDateTime endTime);
 
-    List<Map<String, Object>> selectHomeTodayProductionPlan(@Param("size") Long size);
+    List<Map<String, Object>> selectHomeTodayProductionPlan(@Param("size") Long size,
+                                                             @Param("planStart") LocalDateTime planStart,
+                                                             @Param("planEnd") LocalDateTime planEnd);
 
-    Long countHomeTodayProductionPlan();
+    Long countHomeTodayProductionPlan(@Param("planStart") LocalDateTime planStart,
+                                      @Param("planEnd") LocalDateTime planEnd);
 
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
index 2377dc3..8878006 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
@@ -8,6 +8,8 @@
 
     R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation);
 
+    R updateRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation);
+
     R deleteRouteItem(Long id);
 
     int sortRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation);
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
index 31cdc79..c6256a8 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -23,6 +23,7 @@
 import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
 import com.ruoyi.production.pojo.ProductionProductMain;
 import com.ruoyi.production.service.ProductionBomStructureService;
+import com.ruoyi.production.util.TaskPlanQuantityUtil;
 import com.ruoyi.technology.mapper.TechnologyOperationMapper;
 import com.ruoyi.technology.mapper.TechnologyOperationParamMapper;
 import com.ruoyi.technology.mapper.TechnologyParamMapper;
@@ -262,7 +263,7 @@
                 .filter(item -> item != null && item.getId() != null)
                 .collect(Collectors.toMap(ProductionOrderRoutingOperation::getId, item -> item, (left, right) -> left));
         // Keep task plan quantities aligned with the same order BOM snapshot demand used during snapshot creation.
-        Map<String, BigDecimal> demandedQuantityMap = buildOperationDemandedQuantityMap(structureList, rootProductModelId);
+        Map<String, BigDecimal> demandedQuantityMap = TaskPlanQuantityUtil.buildOperationDemandedQuantityMap(structureList, rootProductModelId);
         for (ProductionOperationTask task : taskList) {
             if (task == null || task.getId() == null || task.getProductionOrderRoutingOperationId() == null) {
                 continue;
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
index 3d16a07..75d0696 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
@@ -4,21 +4,15 @@
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
-import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
-import com.ruoyi.production.mapper.ProductionOrderRoutingOperationParamMapper;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
-import com.ruoyi.production.pojo.ProductionOperationTask;
-import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
-import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
-import com.ruoyi.production.pojo.ProductionProductMain;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.util.TaskPlanQuantityUtil;
+import com.ruoyi.technology.mapper.*;
+import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductionOrderRoutingOperationService;
 import com.ruoyi.production.service.ProductionProductMainService;
-import com.ruoyi.technology.mapper.TechnologyOperationParamMapper;
-import com.ruoyi.technology.mapper.TechnologyParamMapper;
-import com.ruoyi.technology.pojo.TechnologyOperationParam;
-import com.ruoyi.technology.pojo.TechnologyParam;
+import com.ruoyi.technology.pojo.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -26,8 +20,7 @@
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 @Service
 @Transactional(rollbackFor = Exception.class)
@@ -42,6 +35,11 @@
     private final TechnologyOperationParamMapper technologyOperationParamMapper;
     private final TechnologyParamMapper technologyParamMapper;
     private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
 
     @Override
     public R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
@@ -102,6 +100,109 @@
             productionOperationTaskMapper.insert(productionOperationTask);
         }
         return R.ok();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R updateRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        Long operationId = productionOrderRoutingOperation.getId();
+
+        // 鏇存柊宸ヨ壓璺嚎宸ュ簭
+        productionOrderRoutingOperationMapper.updateById(productionOrderRoutingOperation);
+
+        // 閲嶆柊鏌ヨ瀹屾暣璁板綍锛堝墠绔彲鑳芥病鏈変紶閫掓墍鏈夊瓧娈碉紝濡� productionOrderId锛�
+        ProductionOrderRoutingOperation updatedOperation = productionOrderRoutingOperationMapper.selectById(operationId);
+        if (updatedOperation == null) {
+            throw new ServiceException("宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+        }
+
+        // 鏌ヨ鏄惁瀛樺湪宸ュ崟
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
+                new LambdaQueryWrapper<ProductionOperationTask>()
+                        .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, operationId)
+                        .last("limit 1"));
+
+        // 鏍规嵁鏄惁闇�瑕佺敓浜ц繘琛屽鐞�
+        Boolean isProduction = updatedOperation.getIsProduction();
+
+        if (Boolean.TRUE.equals(isProduction)) {
+            // 闇�瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯鐢熸垚
+            if (productionOperationTask == null) {
+                ProductionOperationTask task = new ProductionOperationTask();
+                task.setProductionOrderRoutingOperationId(updatedOperation.getId());
+                task.setProductionOrderId(updatedOperation.getProductionOrderId());
+                // 鑾峰彇鐢熶骇璁㈠崟
+                ProductionOrder productionOrder = productionOrderMapper.selectById(updatedOperation.getProductionOrderId());
+                if (productionOrder == null) {
+                    throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+                }
+
+                // 鑾峰彇璁㈠崟BOM
+                ProductionOrderBom orderBom = productionOrderBomMapper.selectOne(
+                        Wrappers.<ProductionOrderBom>lambdaQuery()
+                                .eq(ProductionOrderBom::getProductionOrderId, productionOrder.getId()));
+
+                // 纭畾鏍逛骇鍝佽鏍糏D
+                Long rootProductModelId = orderBom != null && orderBom.getProductModelId() != null
+                        ? orderBom.getProductModelId()
+                        : productionOrder.getProductModelId();
+
+                // 鑾峰彇BOM缁撴瀯鍒楄〃
+                List<ProductionBomStructure> orderBomStructureList = orderBom == null || orderBom.getId() == null
+                        ? Collections.emptyList()
+                        : productionBomStructureMapper.selectList(
+                        Wrappers.<ProductionBomStructure>lambdaQuery()
+                                .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId())
+                                .orderByAsc(ProductionBomStructure::getId));
+
+                // 鏋勫缓宸ュ簭闇�姹傞噺鏄犲皠
+                Map<String, BigDecimal> operationDemandedQuantityMap =
+                        TaskPlanQuantityUtil.buildOperationDemandedQuantityMap(orderBomStructureList, rootProductModelId);
+
+                // 鑾峰彇宸ヨ壓璺嚎宸ュ簭锛堢敤浜庤绠楄鍒掓暟閲忥級
+                TechnologyRoutingOperation sourceOperation = technologyRoutingOperationMapper.selectById(
+                        updatedOperation.getTechnologyRoutingOperationId());
+                // 灏嗗師鏉ョ殑绉佹湁鏂规硶鏇挎崲涓鸿皟鐢ㄥ伐鍏风被
+                BigDecimal planQuantity = TaskPlanQuantityUtil.resolveTaskPlanQuantity(
+                        sourceOperation,
+                        operationDemandedQuantityMap,
+                        productionOrder,
+                        rootProductModelId);
+                task.setPlanQuantity(planQuantity);
+                task.setCompleteQuantity(BigDecimal.ZERO);
+                task.setWorkOrderNo(generateNextTaskNo());
+                task.setStatus(2);
+                productionOperationTaskMapper.insert(task);
+            }
+        } else {
+            // 涓嶉渶瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦�
+            if (productionOperationTask != null) {
+                validateTaskCanRemove(productionOperationTask);
+                // 娌℃湁鎶ュ伐锛屽垯鍒犻櫎宸ュ崟
+                productionOperationTaskMapper.deleteById(productionOperationTask.getId());
+            }
+        }
+
+        return R.ok();
+    }
+
+    private void validateTaskCanRemove(ProductionOperationTask task) {
+        if (task == null || task.getId() == null) {
+            return;
+        }
+        if (defaultDecimal(task.getCompleteQuantity()).compareTo(BigDecimal.ZERO) > 0) {
+            throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ簭蹇収");
+        }
+        long reportCount = productionProductMainMapper.selectCount(
+                Wrappers.<ProductionProductMain>lambdaQuery()
+                        .eq(ProductionProductMain::getProductionOperationTaskId, task.getId()));
+        if (reportCount > 0) {
+            throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ崟");
+        }
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
     }
 
     @Override
@@ -182,4 +283,24 @@
         }
         return 0;
     }
+
+    private String generateNextTaskNo() {
+        // 鐢熸垚涓嬩竴涓敓浜у伐鍗曞彿
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String prefix = "GD" + datePrefix;
+        ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .likeRight(ProductionOperationTask::getWorkOrderNo, prefix)
+                        .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+                        .last("limit 1"));
+        int sequence = 1;
+        if (lastTask != null && lastTask.getWorkOrderNo() != null && lastTask.getWorkOrderNo().startsWith(prefix)) {
+            try {
+                sequence = Integer.parseInt(lastTask.getWorkOrderNo().substring(prefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return prefix + String.format("%03d", sequence);
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java b/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java
new file mode 100644
index 0000000..e82d7e4
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java
@@ -0,0 +1,137 @@
+package com.ruoyi.production.util;
+
+import com.ruoyi.production.pojo.ProductionBomStructure;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
+import lombok.experimental.UtilityClass;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 宸ュ崟璁″垝鏁伴噺璁$畻宸ュ叿绫�
+ */
+@UtilityClass
+public class TaskPlanQuantityUtil {
+
+    /**
+     * 璁$畻宸ュ崟璁″垝鏁伴噺锛堜娇鐢� TechnologyRoutingOperation锛�
+     */
+    public BigDecimal resolveTaskPlanQuantity(TechnologyRoutingOperation sourceOperation,
+                                              Map<String, BigDecimal> operationDemandedQuantityMap,
+                                              ProductionOrder productionOrder,
+                                              Long rootProductModelId) {
+        if (sourceOperation == null || operationDemandedQuantityMap == null || operationDemandedQuantityMap.isEmpty()) {
+            return defaultDecimal(productionOrder == null ? null : productionOrder.getQuantity());
+        }
+        Long outputProductModelId = sourceOperation.getProductModelId() != null
+                ? sourceOperation.getProductModelId()
+                : rootProductModelId;
+        String key = buildOperationDemandedQuantityKey(sourceOperation.getTechnologyOperationId(), outputProductModelId);
+        BigDecimal planQuantity = operationDemandedQuantityMap.get(key);
+        return planQuantity != null ? planQuantity : defaultDecimal(productionOrder == null ? null : productionOrder.getQuantity());
+    }
+
+    /**
+     * 璁$畻宸ュ崟璁″垝鏁伴噺锛堜娇鐢� ProductionOrderRoutingOperation锛�
+     */
+    public BigDecimal resolveTaskPlanQuantity(ProductionOrderRoutingOperation routingOperation,
+                                              Map<String, BigDecimal> demandedQuantityMap,
+                                              BigDecimal orderQuantity,
+                                              Long rootProductModelId) {
+        if (routingOperation == null || demandedQuantityMap == null || demandedQuantityMap.isEmpty()) {
+            return orderQuantity;
+        }
+        Long outputProductModelId = routingOperation.getProductModelId() != null
+                ? routingOperation.getProductModelId()
+                : rootProductModelId;
+        String key = buildOperationDemandedQuantityKey(routingOperation.getTechnologyOperationId(), outputProductModelId);
+        BigDecimal planQuantity = demandedQuantityMap.get(key);
+        return planQuantity != null ? planQuantity : orderQuantity;
+    }
+
+    /**
+     * 鏋勫缓宸ュ簭闇�姹傞噺鏄犲皠琛�
+     */
+    public Map<String, BigDecimal> buildOperationDemandedQuantityMap(List<ProductionBomStructure> bomStructures, Long rootProductModelId) {
+        if (bomStructures == null || bomStructures.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<Long, ProductionBomStructure> structureById = new HashMap<>();
+        for (ProductionBomStructure item : bomStructures) {
+            if (item != null && item.getId() != null) {
+                structureById.put(item.getId(), item);
+            }
+        }
+        Map<String, BigDecimal> demandedQuantityMap = new HashMap<>();
+        Set<String> mergedOutputNodeKeySet = new HashSet<>();
+        for (ProductionBomStructure bomStructure : bomStructures) {
+            if (bomStructure == null || bomStructure.getTechnologyOperationId() == null) {
+                continue;
+            }
+            ProductionBomStructure outputNode = resolveOperationOutputNode(bomStructure, structureById);
+            Long outputProductModelId = resolveOutputProductModelId(outputNode, rootProductModelId);
+            if (outputProductModelId == null) {
+                continue;
+            }
+            String mergedOutputNodeKey = buildOperationOutputNodeKey(bomStructure.getTechnologyOperationId(),
+                    outputNode == null ? null : outputNode.getId(), outputProductModelId);
+            if (!mergedOutputNodeKeySet.add(mergedOutputNodeKey)) {
+                continue;
+            }
+            BigDecimal demandedQuantity = defaultDecimal(outputNode == null ? null : outputNode.getDemandedQuantity());
+            String key = buildOperationDemandedQuantityKey(bomStructure.getTechnologyOperationId(), outputProductModelId);
+            demandedQuantityMap.merge(key, demandedQuantity, BigDecimal::add);
+        }
+        return demandedQuantityMap;
+    }
+
+    /**
+     * 鏋勫缓宸ュ簭闇�姹傞噺key
+     */
+    public String buildOperationDemandedQuantityKey(Long operationId, Long outputProductModelId) {
+        return String.valueOf(operationId) + "#" + String.valueOf(outputProductModelId);
+    }
+
+    /**
+     * 鏋勫缓杈撳嚭鑺傜偣key
+     */
+    public String buildOperationOutputNodeKey(Long operationId, Long outputNodeId, Long outputProductModelId) {
+        return String.valueOf(operationId) + "#" + String.valueOf(outputNodeId) + "#" + String.valueOf(outputProductModelId);
+    }
+
+    /**
+     * 瑙f瀽宸ュ簭杈撳嚭鑺傜偣
+     */
+    public ProductionBomStructure resolveOperationOutputNode(ProductionBomStructure bomStructure,
+                                                             Map<Long, ProductionBomStructure> structureById) {
+        if (bomStructure == null) {
+            return null;
+        }
+        if (bomStructure.getParentId() == null) {
+            return bomStructure;
+        }
+        ProductionBomStructure parent = structureById.get(bomStructure.getParentId());
+        return parent != null ? parent : bomStructure;
+    }
+
+    /**
+     * 瑙f瀽杈撳嚭浜у搧瑙勬牸ID
+     */
+    public Long resolveOutputProductModelId(ProductionBomStructure outputNode, Long rootProductModelId) {
+        if (outputNode == null) {
+            return rootProductModelId;
+        }
+        return outputNode.getProductModelId() != null ? outputNode.getProductModelId() : rootProductModelId;
+    }
+
+    /**
+     * 榛樿BigDecimal鍊�
+     */
+    public BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java b/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
index be53963..cc295d5 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -2,6 +2,8 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.dto.QualityInspectDto;
 import com.ruoyi.quality.pojo.QualityInspect;
@@ -39,6 +41,7 @@
      */
     @PostMapping("/add")
     @Operation(summary = "鏂板妫�楠�")
+    @Log(title = "鏂板妫�楠�", businessType = BusinessType.INSERT)
     public R<?> add(@RequestBody QualityInspectDto qualityInspectDto) {
         return R.ok(qualityInspectService.add(qualityInspectDto));
     }
@@ -51,6 +54,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎妫�楠�")
+    @Log(title = "鍒犻櫎妫�楠�", businessType = BusinessType.DELETE)
     public R<?> delQualityInspect(@RequestBody List<Integer> ids) {
         if (CollectionUtils.isEmpty(ids)) {
             return R.fail("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
@@ -80,6 +84,7 @@
      */
     @GetMapping("/{id}")
     @Operation(summary = "妫�楠岃鎯�")
+    @Log(title = "妫�楠岃鎯�", businessType = BusinessType.OTHER)
     public R<?> QualityInspectDetail(@PathVariable("id") Integer id) {
         return R.ok(qualityInspectService.getDetailById(id));
     }
@@ -92,6 +97,7 @@
      */
     @PostMapping("/update")
     @Operation(summary = "淇敼妫�楠�")
+    @Log(title = "淇敼妫�楠�", businessType = BusinessType.UPDATE)
     public R<?> update(@RequestBody QualityInspectDto qualityInspectDto) {
         return R.ok(qualityInspectService.updateQualityInspect(qualityInspectDto));
     }
@@ -105,6 +111,7 @@
      */
     @GetMapping("/listPage")
     @Operation(summary = "鍒嗛〉鏌ヨ妫�楠�")
+    @Log(title = "鍒嗛〉鏌ヨ妫�楠�", businessType = BusinessType.OTHER)
     public R<?> qualityInspectListPage(Page page, QualityInspectDto qualityInspect) {
         return R.ok(qualityInspectService.qualityInspectListPage(page, qualityInspect));
     }
@@ -117,6 +124,7 @@
      */
     @PostMapping("/export")
     @Operation(summary = "瀵煎嚭妫�楠�")
+    @Log(title = "瀵煎嚭妫�楠�", businessType = BusinessType.EXPORT)
     public void qualityInspectExport(HttpServletResponse response, QualityInspect qualityInspect) {
         qualityInspectService.qualityInspectExport(response, qualityInspect);
     }
@@ -129,6 +137,7 @@
      */
     @PostMapping("/submit")
     @Operation(summary = "鎻愪氦妫�楠�")
+    @Log(title = "鎻愪氦妫�楠�", businessType = BusinessType.OTHER)
     public R<?> submit(@RequestBody QualityInspect qualityInspect) {
         return R.ok(qualityInspectService.submit(qualityInspect));
     }
@@ -141,6 +150,7 @@
      */
     @PostMapping("/down")
     @Operation(summary = "涓嬭浇妫�楠�")
+    @Log(title = "涓嬭浇妫�楠�", businessType = BusinessType.OTHER)
     public void down(HttpServletResponse response, @RequestBody QualityInspect qualityInspect) {
         qualityInspectService.down(response, qualityInspect);
     }
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java b/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
index 21bfa2e..48fc093 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
@@ -2,6 +2,8 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.pojo.QualityInspect;
 import com.ruoyi.quality.pojo.QualityInspectFile;
@@ -34,6 +36,7 @@
      */
     @GetMapping("/{inspectId}")
     @Operation(summary = "妫�楠屽弬鏁伴」璇︽儏")
+    @Log(title = "妫�楠屽弬鏁伴」璇︽儏", businessType = BusinessType.OTHER)
     public R<?> QualityInspectParamDetail(@PathVariable("inspectId") Integer inspectId) {
         return R.ok(qualityInspectParamService.qualityInspectParamDetail(inspectId));
     }
@@ -46,6 +49,7 @@
      */
     @PostMapping("/update")
     @Operation(summary = "淇敼妫�楠屽弬鏁伴」")
+    @Log(title = "淇敼妫�楠屽弬鏁伴」", businessType = BusinessType.UPDATE)
     public R<?> update(@RequestBody List<QualityInspectParam> qualityInspectParams) {
         return R.ok(qualityInspectParamService.updateBatchById(qualityInspectParams));
     }
@@ -57,6 +61,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎妫�楠屽弬鏁伴」")
+    @Log(title = "鍒犻櫎妫�楠屽弬鏁伴」", businessType = BusinessType.DELETE)
     public R<?> delQualityUnqualified(@RequestBody List<Integer> ids) {
         if(CollectionUtils.isEmpty(ids)){
             return R.fail("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityReportController.java b/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
index 4d005b0..370e8f0 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
@@ -1,6 +1,8 @@
 package com.ruoyi.quality.controller;
 
-import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.service.QualityReportService;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -30,8 +32,9 @@
      */
     @Operation(summary = "鑾峰彇妫�楠岀粺璁℃暟鎹�")
     @GetMapping("/getInspectStatistics")
-    public AjaxResult getInspectStatistics() {
-        return AjaxResult.success(qualityReportService.getInspectStatistics());
+    @Log(title = "鑾峰彇妫�楠岀粺璁℃暟鎹�", businessType = BusinessType.OTHER)
+    public R<?> getInspectStatistics() {
+        return R.ok(qualityReportService.getInspectStatistics());
     }
 
     /**
@@ -39,8 +42,9 @@
      */
     @Operation(summary = "鑾峰彇鍚堟牸鐜囩粺璁℃暟鎹�")
     @GetMapping("/getPassRateStatistics")
-    public AjaxResult getPassRateStatistics() {
-        return AjaxResult.success(qualityReportService.getPassRateStatistics());
+    @Log(title = "鑾峰彇鍚堟牸鐜囩粺璁℃暟鎹�", businessType = BusinessType.OTHER)
+    public R<?> getPassRateStatistics() {
+        return R.ok(qualityReportService.getPassRateStatistics());
     }
 
     /**
@@ -48,8 +52,9 @@
      */
     @Operation(summary = "鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�")
     @GetMapping("/getMonthlyPassRateStatistics")
-    public AjaxResult getMonthlyPassRateStatistics(@RequestParam("year") String year) {
-        return AjaxResult.success(qualityReportService.getMonthlyPassRateStatistics(year));
+    @Log(title = "鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�", businessType = BusinessType.OTHER)
+    public R<?> getMonthlyPassRateStatistics(@RequestParam("year") String year) {
+        return R.ok(qualityReportService.getMonthlyPassRateStatistics(year));
     }
 
     /**
@@ -57,8 +62,9 @@
      */
     @Operation(summary = "鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁")
     @GetMapping("/getYearlyPassRateStatistics")
-    public AjaxResult getYearlyPassRateStatistics(@RequestParam("year") String year) {
-        return AjaxResult.success(qualityReportService.getYearlyPassRateStatistics(year));
+    @Log(title = "鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁", businessType = BusinessType.OTHER)
+    public R<?> getYearlyPassRateStatistics(@RequestParam("year") String year) {
+        return R.ok(qualityReportService.getYearlyPassRateStatistics(year));
     }
 
     /**
@@ -66,8 +72,9 @@
      */
     @Operation(summary = "鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁")
     @GetMapping("/getMonthlyCompletionDetails")
-    public AjaxResult getMonthlyCompletionDetails(@RequestParam("year") String year) {
-        return AjaxResult.success(qualityReportService.getMonthlyCompletionDetails(year));
+    @Log(title = "鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁", businessType = BusinessType.OTHER)
+    public R<?> getMonthlyCompletionDetails(@RequestParam("year") String year) {
+        return R.ok(qualityReportService.getMonthlyCompletionDetails(year));
     }
 
     /**
@@ -75,8 +82,9 @@
      */
     @Operation(summary = "鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�")
     @GetMapping("/getTopParameters")
-    public AjaxResult getTopParameters(@RequestParam("modelType") Integer modelType) {
-        return AjaxResult.success(qualityReportService.getTopParameters(modelType));
+    @Log(title = "鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�", businessType = BusinessType.OTHER)
+    public R<?> getTopParameters(@RequestParam("modelType") Integer modelType) {
+        return R.ok(qualityReportService.getTopParameters(modelType));
     }
 
 }
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardBindingController.java b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardBindingController.java
index e590802..7f2142e 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardBindingController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardBindingController.java
@@ -1,5 +1,7 @@
 package com.ruoyi.quality.controller;
 
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.pojo.QualityTestStandardBinding;
 import com.ruoyi.quality.service.QualityTestStandardBindingService;
@@ -35,6 +37,7 @@
      */
     @PostMapping("/add")
     @Operation(summary = "鏂板妫�娴嬫爣鍑嗕富琛ㄤ笌浜у搧鍏宠仈琛�")
+    @Log(title = "鏂板妫�娴嬫爣鍑嗕富琛ㄤ笌浜у搧鍏宠仈琛�", businessType = BusinessType.INSERT)
     public R<?> add(@RequestBody List<QualityTestStandardBinding> qualityTestStandardBindings) {
         return R.ok(qualityTestStandardBindingService.add(qualityTestStandardBindings));
     }
@@ -47,6 +50,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎妫�娴嬫爣鍑嗕富琛ㄤ笌浜у搧鍏宠仈琛�")
+    @Log(title = "鍒犻櫎妫�娴嬫爣鍑嗕富琛ㄤ笌浜у搧鍏宠仈琛�", businessType = BusinessType.DELETE)
     public R<?> delQualityTestStandard(@RequestBody List<Integer> ids) {
         if (CollectionUtils.isEmpty(ids)) {
             return R.fail("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
@@ -61,6 +65,7 @@
      */
     @GetMapping("/list")
     @Operation(summary = "妫�娴嬫寚鏍囩淮鎶ゆ煡璇�")
+    @Log(title = "妫�娴嬫寚鏍囩淮鎶ゆ煡璇�", businessType = BusinessType.OTHER)
     public R<?> listBinding(Long testStandardId) {
         return R.ok(qualityTestStandardBindingService.listBinding(testStandardId));
     }
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
index 0ccfd65..ab8fca9 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
@@ -2,6 +2,8 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.pojo.QualityTestStandard;
 import com.ruoyi.quality.pojo.QualityTestStandardParam;
@@ -43,6 +45,7 @@
      */
     @PostMapping("/add")
     @Operation(summary = "鏂板妫�娴嬫爣鍑嗕富琛�")
+    @Log(title = "鏂板妫�娴嬫爣鍑嗕富琛�", businessType = BusinessType.INSERT)
     public R<?> add(@RequestBody QualityTestStandard qualityTestStandard) {
         return R.ok(qualityTestStandardService.save(qualityTestStandard));
     }
@@ -54,6 +57,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎妫�娴嬫爣鍑嗕富琛�")
+    @Log(title = "鍒犻櫎妫�娴嬫爣鍑嗕富琛�", businessType = BusinessType.DELETE)
     public R<?> delQualityTestStandard(@RequestBody List<Integer> ids) {
         if(CollectionUtils.isEmpty(ids)){
             return R.fail("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
@@ -68,6 +72,7 @@
      */
     @PostMapping("/update")
     @Operation(summary = "妫�娴嬫爣鍑嗕富琛ㄤ慨鏀�")
+    @Log(title = "妫�娴嬫爣鍑嗕富琛ㄤ慨鏀�", businessType = BusinessType.UPDATE)
     public R<?> update(@RequestBody QualityTestStandard qualityTestStandard) {
         return R.ok(qualityTestStandardService.updateById(qualityTestStandard));
     }
@@ -80,6 +85,7 @@
      */
     @GetMapping("/listPage")
     @Operation(summary = "妫�娴嬫爣鍑嗕富琛ㄥ垎椤垫煡璇�")
+    @Log(title = "妫�娴嬫爣鍑嗕富琛ㄥ垎椤垫煡璇�", businessType = BusinessType.OTHER)
     public R<?> qualityTestStandardListPage(Page page, QualityTestStandard qualityTestStandard) {
         return R.ok(qualityTestStandardService.qualityTestStandardListPage(page, qualityTestStandard));
     }
@@ -91,6 +97,7 @@
      */
     @PostMapping("/copyParam")
     @Operation(summary = "妫�娴嬫爣鍑嗗鍒跺弬鏁�")
+    @Log(title = "妫�娴嬫爣鍑嗗鍒跺弬鏁�", businessType = BusinessType.OTHER)
     public R<?> copyParam(@RequestBody QualityTestStandard qualityTestStandard) {
         return R.ok(qualityTestStandardService.copyParam(qualityTestStandard));
     }
@@ -102,6 +109,7 @@
      */
     @PostMapping("/qualityTestStandardAudit")
     @Operation(summary = "妫�娴嬫爣鍑嗘壒閲忓鏍�")
+    @Log(title = "妫�娴嬫爣鍑嗘壒閲忓鏍�", businessType = BusinessType.OTHER)
     public R<?> qualityTestStandardAudit(@RequestBody List<QualityTestStandard> qualityTestStandards) {
         return R.ok(qualityTestStandardService.updateBatchById(qualityTestStandards));
     }
@@ -112,6 +120,7 @@
      */
     @GetMapping("/getQualityTestStandardByProductId")
     @Operation(summary = "鏍规嵁浜у搧id鏌ヨ鐩稿叧鐨勬楠屾爣鍑�")
+    @Log(title = "鏍规嵁浜у搧id鏌ヨ鐩稿叧鐨勬楠屾爣鍑�", businessType = BusinessType.OTHER)
     public R<?> getQualityTestStandardByProductId(@Nonnull Long productId, @Nonnull Integer inspectType, String process) {
         return R.ok(qualityTestStandardService.getQualityTestStandardByProductId(productId,inspectType,process));
     }
@@ -122,6 +131,7 @@
      */
     @GetMapping("/getQualityTestStandardParamByTestStandardId")
     @Operation(summary = "鏍规嵁妫�娴嬫爣鍑唅d鏌ヨ鐩稿叧鐨勬楠屾爣鍑嗗弬鏁�")
+    @Log(title = "鏍规嵁妫�娴嬫爣鍑唅d鏌ヨ鐩稿叧鐨勬楠屾爣鍑嗗弬鏁�", businessType = BusinessType.OTHER)
     public R<?> getQualityTestStandardParamByTestStandardId(Long testStandardId) {
         return R.ok(qualityTestStandardParamService.list(Wrappers.<QualityTestStandardParam>lambdaQuery().eq(QualityTestStandardParam::getTestStandardId, testStandardId)));
     }
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardParamController.java b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardParamController.java
index a12535b..16788c9 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardParamController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardParamController.java
@@ -2,6 +2,8 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.pojo.QualityTestStandard;
 import com.ruoyi.quality.pojo.QualityTestStandardParam;
@@ -38,6 +40,7 @@
      */
     @PostMapping("/add")
     @Operation(summary = "鏂板妫�娴嬫爣鍑嗗弬鏁�")
+    @Log(title = "鏂板妫�娴嬫爣鍑嗗弬鏁�", businessType = BusinessType.INSERT)
     public R<?> add(@RequestBody QualityTestStandardParam qualityTestStandardParam) {
         return R.ok(qualityTestStandardParamService.save(qualityTestStandardParam));
     }
@@ -49,6 +52,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎妫�娴嬫寚鏍囩淮鎶�")
+    @Log(title = "鍒犻櫎妫�娴嬫寚鏍囩淮鎶�", businessType = BusinessType.DELETE)
     public R<?> delQualityTestStandard(@RequestBody List<Integer> ids) {
         if(CollectionUtils.isEmpty(ids)){
             return R.fail("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
@@ -63,6 +67,7 @@
      */
     @PostMapping("/update")
     @Operation(summary = "妫�娴嬫寚鏍囩淮鎶や慨鏀�")
+    @Log(title = "妫�娴嬫寚鏍囩淮鎶や慨鏀�", businessType = BusinessType.UPDATE)
     public R<?> update(@RequestBody QualityTestStandardParam qualityTestStandardParam) {
         return R.ok(qualityTestStandardParamService.updateById(qualityTestStandardParam));
     }
@@ -73,6 +78,7 @@
      */
     @GetMapping("/list")
     @Operation(summary = "妫�娴嬫寚鏍囩淮鎶ゆ煡璇�")
+    @Log(title = "妫�娴嬫寚鏍囩淮鎶ゆ煡璇�", businessType = BusinessType.OTHER)
     public R<?> list(Long testStandardId) {
         return R.ok(qualityTestStandardParamService.list(Wrappers.<QualityTestStandardParam>lambdaQuery().eq(QualityTestStandardParam::getTestStandardId,testStandardId)));
     }
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
index 020841f..a2222c3 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -1,6 +1,8 @@
 package com.ruoyi.quality.controller;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.quality.pojo.QualityUnqualified;
 import com.ruoyi.quality.service.IQualityUnqualifiedService;
@@ -32,6 +34,7 @@
      */
     @PostMapping("/add")
     @Operation(summary = "鏂板涓嶅悎鏍肩鐞�")
+    @Log(title = "鏂板涓嶅悎鏍肩鐞�", businessType = BusinessType.INSERT)
     public R<?> add(@RequestBody QualityUnqualified qualityUnqualified) {
         qualityUnqualified.setInspectState(0);
         return R.ok(qualityUnqualifiedService.save(qualityUnqualified));
@@ -44,6 +47,7 @@
      */
     @DeleteMapping("/del")
     @Operation(summary = "鍒犻櫎涓嶅悎鏍肩鐞�")
+    @Log(title = "鍒犻櫎涓嶅悎鏍肩鐞�", businessType = BusinessType.DELETE)
     public R<?> delQualityUnqualified(@RequestBody List<Integer> ids) {
        qualityUnqualifiedService.listByIds(ids).stream().forEach(qualityUnqualified -> {
            if (qualityUnqualified.getInspectState()==1){
@@ -60,6 +64,7 @@
      */
     @GetMapping("/{id}")
     @Operation(summary = "涓嶅悎鏍肩鐞嗚鎯�")
+    @Log(title = "涓嶅悎鏍肩鐞嗚鎯�", businessType = BusinessType.OTHER)
     public R<?> QualityUnqualifiedDetail(@PathVariable("id") Integer id) {
         return R.ok(qualityUnqualifiedService.getUnqualified(id));
     }
@@ -71,6 +76,7 @@
      */
     @PostMapping("/update")
     @Operation(summary = "涓嶅悎鏍肩鐞嗕慨鏀�")
+    @Log(title = "涓嶅悎鏍肩鐞嗕慨鏀�", businessType = BusinessType.UPDATE)
     public R<?> update(@RequestBody QualityUnqualified qualityUnqualified) {
         return R.ok(qualityUnqualifiedService.updateById(qualityUnqualified));
     }
@@ -83,6 +89,7 @@
      */
     @GetMapping("/listPage")
     @Operation(summary = "涓嶅悎鏍肩鐞嗗垎椤垫煡璇�")
+    @Log(title = "涓嶅悎鏍肩鐞嗗垎椤垫煡璇�", businessType = BusinessType.OTHER)
     public R<?> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified) {
         return R.ok(qualityUnqualifiedService.qualityUnqualifiedListPage(page, qualityUnqualified));
     }
@@ -94,6 +101,7 @@
      */
     @PostMapping("/export")
     @Operation(summary = "涓嶅悎鏍肩鐞嗗鍑�")
+    @Log(title = "涓嶅悎鏍肩鐞嗗鍑�", businessType = BusinessType.EXPORT)
     public void qualityUnqualifiedExport(HttpServletResponse response,QualityUnqualified qualityUnqualified) {
         qualityUnqualifiedService.qualityUnqualifiedExport(response, qualityUnqualified);
     }
@@ -105,6 +113,7 @@
      */
     @PostMapping("/deal")
     @Operation(summary = "涓嶅悎鏍肩鐞嗗鐞�")
+    @Log(title = "涓嶅悎鏍肩鐞嗗鐞�", businessType = BusinessType.OTHER)
     public R<?> deal(@RequestBody QualityUnqualified qualityUnqualified) {
         return R.ok(qualityUnqualifiedService.deal(qualityUnqualified));
     }
diff --git a/src/main/resources/approve-todo-agent-prompt.txt b/src/main/resources/approve-todo-agent-prompt.txt
index c309da8..f026fee 100644
--- a/src/main/resources/approve-todo-agent-prompt.txt
+++ b/src/main/resources/approve-todo-agent-prompt.txt
@@ -1,4 +1,5 @@
 浣犳槸涓�涓鎵瑰緟鍔炲姪鎵嬶紝璐熻矗鍗忓悓鍔炲叕瀹℃壒寰呭姙鐨勬煡璇€�佸鏍搞�佸彇娑堝鏍搞�佷慨鏀广�佸垹闄ゅ拰缁熻鍒嗘瀽銆�
+褰撳墠鏃ユ湡锛歿{currentDate}}锛堜腑鍥芥椂鍖猴級銆�
 
 宸ヤ綔瑕佹眰锛�
 1. 鐢ㄦ埛闂緟鍔炲垪琛ㄣ�佸鎵硅繘搴︺�佸鎵硅鎯呫�佺粺璁℃暟鎹椂锛屼紭鍏堣皟鐢ㄥ伐鍏凤紝涓嶈鑷嗛�犳暟鎹��
@@ -16,3 +17,4 @@
 13. 鍙湁鈥滄煡璇㈠鎵瑰緟鍔炶鎯呪�濊繖涓伐鍏峰厑璁歌緭鍑鸿嚜鐒惰瑷�鏂囨湰銆�
 14. 濡傛灉宸ュ叿杩斿洖鐨勬槸缁熻 JSON锛屼篃鍚屾牱鐩存帴杈撳嚭鍘熷 JSON锛涘叾涓� `description`銆乣summary`銆乣charts` 宸茬粡渚涘墠绔娇鐢ㄣ��
 15. 鍥炵瓟浣跨敤涓枃锛涗絾鍦� JSON 鍦烘櫙涓嬶紝鏈�缁堣緭鍑哄繀椤绘槸鍚堟硶 JSON 鏈綋銆�
+16. 鐢ㄦ埛鎻愬埌鈥滀粖骞�/鏈湀/浠婂ぉ/鏈�杩�/涓婃湀/鍘诲勾鈥濈瓑鐩稿鏃堕棿鏃讹紝蹇呴』涓ユ牸鍩轰簬鈥滃綋鍓嶆棩鏈熲�濇崲绠楋紝绂佹鑷鍋囪骞翠唤銆�
diff --git a/src/main/resources/manufacturing-agent-prompt.txt b/src/main/resources/manufacturing-agent-prompt.txt
index c1a30c8..1653bb9 100644
--- a/src/main/resources/manufacturing-agent-prompt.txt
+++ b/src/main/resources/manufacturing-agent-prompt.txt
@@ -1,4 +1,5 @@
 浣犳槸浼佷笟鍒堕�犳櫤鑳藉姪鎵嬶紝瑕嗙洊鐢熶骇鐜板満銆佽鍒掋�佸伐鍗曘�佽澶囥�佽川閲忋�佺墿鏂欍�佸紓甯稿鐞嗕竷涓煙銆�
+褰撳墠鏃ユ湡锛歿{currentDate}}锛堜腑鍥芥椂鍖猴級銆�
 
 宸ヤ綔瑙勫垯锛�
 1. 鐢ㄦ埛鎻愬嚭鈥滄煡銆侀棶銆侀璀︺�佸垎鏋愨�濋渶姹傛椂锛屼紭鍏堣皟鐢ㄥ伐鍏锋嬁缁撴瀯鍖栫粨鏋滐紝涓嶈鑷嗛�犱笟鍔℃暟鎹��
@@ -6,3 +7,4 @@
 3. 宸ュ叿杩斿洖 JSON 鏃讹紝鐩存帴杈撳嚭鍘熷 JSON 瀛楃涓诧紝涓嶈棰濆鍖呰9 Markdown锛屼笉瑕佸湪鍓嶅悗鍔犺В閲婃枃瀛椼��
 4. 鍥炵瓟蹇呴』浣跨敤涓枃锛涜嫢鐢ㄦ埛闂缂哄皯鏃堕棿鑼冨洿銆佸叧閿瓧绛夋潯浠讹紝鍙厛缁欓粯璁ゅ彛寰勫苟鎻愮ず鍙ˉ鍏呮潯浠躲��
 5. 鑻ユ棤娉曚粠宸ュ叿缁撴灉寰楀埌缁撹锛屾槑纭鏄庣己灏戠殑绛涢�夋潯浠舵垨涓氬姟瀛楁銆�
+6. 鐢ㄦ埛鎻愬埌鈥滀粖骞�/鏈湀/浠婂ぉ/鏈�杩�/涓婃湀/鍘诲勾鈥濈瓑鐩稿鏃堕棿鏃讹紝蹇呴』涓ユ牸鍩轰簬鈥滃綋鍓嶆棩鏈熲�濇崲绠楋紝绂佹鑷鍋囪骞翠唤銆�
diff --git a/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml b/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
index f029ef7..199eb21 100644
--- a/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
@@ -64,6 +64,9 @@
             <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>
diff --git a/src/main/resources/mapper/production/ProductionOrderMapper.xml b/src/main/resources/mapper/production/ProductionOrderMapper.xml
index 95679a7..8e64413 100644
--- a/src/main/resources/mapper/production/ProductionOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -227,6 +227,10 @@
             <if test="status != null">
                 and po.status = #{status}
             </if>
+            <if test="startTime != null and endTime != null">
+                and po.create_time &gt;= #{startTime}
+                and po.create_time &lt; #{endTime}
+            </if>
         </where>
         order by po.id desc
         limit #{offset}, #{size}
@@ -239,13 +243,21 @@
             <if test="status != null">
                 and po.status = #{status}
             </if>
+            <if test="startTime != null and endTime != null">
+                and po.create_time &gt;= #{startTime}
+                and po.create_time &lt; #{endTime}
+            </if>
         </where>
     </select>
 
     <select id="countHomeOrderProgressByStatus" resultType="java.util.Map">
         select po.status as status, count(1) as cnt
         from production_order po
-        where po.status in (2, 3, 4)
+        where po.status in (1, 2, 3, 4)
+        <if test="startTime != null and endTime != null">
+            and po.create_time &gt;= #{startTime}
+            and po.create_time &lt; #{endTime}
+        </if>
         group by po.status
     </select>
 
@@ -258,7 +270,13 @@
         from production_order po
                  left join product_model pm on po.product_model_id = pm.id
                  left join product p on pm.product_id = p.id
-        where po.status in (1, 2)
+        <where>
+            po.status in (1, 2)
+            <if test="planStart != null and planEnd != null">
+                and po.plan_complete_time &gt;= #{planStart}
+                and po.plan_complete_time &lt; #{planEnd}
+            </if>
+        </where>
         order by case when po.status = 2 then 0 else 1 end, po.id desc
         limit #{size}
     </select>
@@ -266,7 +284,13 @@
     <select id="countHomeTodayProductionPlan" resultType="java.lang.Long">
         select count(1)
         from production_order po
-        where po.status in (1, 2)
+        <where>
+            po.status in (1, 2)
+            <if test="planStart != null and planEnd != null">
+                and po.plan_complete_time &gt;= #{planStart}
+                and po.plan_complete_time &lt; #{planEnd}
+            </if>
+        </where>
     </select>
 
 </mapper>
diff --git a/src/main/resources/purchase-agent-prompt.txt b/src/main/resources/purchase-agent-prompt.txt
index 97f7eb2..2fd5021 100644
--- a/src/main/resources/purchase-agent-prompt.txt
+++ b/src/main/resources/purchase-agent-prompt.txt
@@ -1,5 +1,6 @@
 浣犳槸浼佷笟閲囪喘鏅鸿兘鍔╃悊銆�
 浣犵殑鐩爣鏄府鍔╃敤鎴峰揩閫熷畬鎴愰噰璐浉鍏充俊鎭煡璇笌瑙h銆�
+褰撳墠鏃ユ湡锛歿{currentDate}}锛堜腑鍥芥椂鍖猴級銆�
 
 宸ヤ綔瑙勫垯锛�
 1. 浼樺厛璋冪敤宸ュ叿鍑芥暟鑾峰彇閲囪喘鍙拌处銆佷粯娆俱�佸彂绁ㄣ�侀��璐х瓑缁撴瀯鍖栨暟鎹��
@@ -9,6 +10,8 @@
 5. 鐢ㄦ埛闂�滄渶杩�7澶╀緵搴斿晢鍒拌揣寮傚父鈥濃�滃埌璐ч棶棰樷�濃�滃埌璐у紓甯糕�濇椂锛岃皟鐢ㄢ�滄煡璇㈤噰璐埌璐у紓甯糕�濄��
 6. 鐢ㄦ埛闂�滃緟浠樻閲囪喘鍗曗�濃�滄湭浠樻閲囪喘鍗曗�濃�滄湭浠樻竻閲囪喘璁㈠崟鈥濇椂锛岃皟鐢ㄢ�滄煡璇㈠緟浠樻閲囪喘鍗曗�濄��
 7. 鐢ㄦ埛闂�滄湰鏈堥噰璐��璐ф儏鍐碘�濃�滈噰璐��璐у垪琛ㄢ�濃�滈��鏂�/鎷掓敹鎯呭喌鈥濇椂锛岃皟鐢ㄢ�滄煡璇㈤噰璐��璐ф儏鍐碘�濄��
-8. 缁撴灉鐢ㄧ畝娲佷腑鏂囧洖绛旓紝鍏堢粰缁撹锛屽啀缁欏叧閿暟鎹偣銆�
-9. 涓嶈缂栭�犻噰璐暟鎹紝鎵�鏈夌粨璁哄繀椤诲熀浜庡伐鍏疯繑鍥炪��
-10. 鏃犳硶鐩存帴寰楀嚭缁撹鏃讹紝鏄庣‘璇存槑缂哄皯鍝簺瀛楁鎴栫瓫閫夋潯浠躲��
+8. 宸ュ叿杩斿洖 JSON 鏃讹紝鐩存帴杈撳嚭鍘熷 JSON 瀛楃涓诧紝涓嶈棰濆鍖呰9 Markdown锛屼篃涓嶈鍦ㄥ墠鍚庤拷鍔犺В閲婃枃鏈��
+9. 鍙湁鍦ㄦ湭璋冪敤 JSON 宸ュ叿鏃讹紝鎵嶄娇鐢ㄧ畝娲佷腑鏂囧洖绛旓紝鍏堢粰缁撹锛屽啀缁欏叧閿暟鎹偣銆�
+10. 涓嶈缂栭�犻噰璐暟鎹紝鎵�鏈夌粨璁哄繀椤诲熀浜庡伐鍏疯繑鍥炪��
+11. 鏃犳硶鐩存帴寰楀嚭缁撹鏃讹紝鏄庣‘璇存槑缂哄皯鍝簺瀛楁鎴栫瓫閫夋潯浠躲��
+12. 鐢ㄦ埛鎻愬埌鈥滀粖骞�/鏈湀/浠婂ぉ/鏈�杩�/涓婃湀/鍘诲勾鈥濈瓑鐩稿鏃堕棿鏃讹紝蹇呴』涓ユ牸鍩轰簬鈥滃綋鍓嶆棩鏈熲�濇崲绠楋紝绂佹鑷鍋囪骞翠唤銆�
diff --git a/src/main/resources/sales-agent-prompt.txt b/src/main/resources/sales-agent-prompt.txt
index 5cd87ff..3a43502 100644
--- a/src/main/resources/sales-agent-prompt.txt
+++ b/src/main/resources/sales-agent-prompt.txt
@@ -1,7 +1,9 @@
 浣犳槸浼佷笟閿�鍞姪鎵嬶紝瑕嗙洊瀹㈡埛妗f銆侀攢鍞姤浠枫�侀攢鍞彴璐︺�侀攢鍞��璐с�佸鎴峰線鏉ャ�佸彂璐у彴璐︺�佹寚鏍囩粺璁°�佸鎴锋祦澶遍闄╁垎鏋愩�佸洖娆句笌鎶ヤ环绛栫暐寤鸿绛夊満鏅��
+褰撳墠鏃ユ湡锛歿{currentDate}}锛堜腑鍥芥椂鍖猴級銆�
 宸ヤ綔瑙勫垯锛�
 1. 鐢ㄦ埛鎻愬嚭鈥滄煡銆侀棶銆佺粺璁°�佸垎鏋愩�佸缓璁�濋渶姹傛椂锛屼紭鍏堣皟鐢ㄥ伐鍏疯繑鍥炵粨鏋勫寲鏁版嵁锛屼笉缂栭�犱笟鍔℃暟鎹��
 2. 鍛戒腑鈥滃鎴锋祦澶遍闄╁垎鏋愨�濇垨鈥滃洖娆句笌鎶ヤ环绛栫暐寤鸿鈥濇椂锛屼紭鍏堜娇鐢ㄥ伐鍏疯緭鍑虹粨鏋勫寲 JSON銆�
 3. 宸ュ叿杩斿洖 JSON 鏃讹紝鐩存帴杈撳嚭鍘熷 JSON 瀛楃涓诧紝涓嶈棰濆鍖呰9 Markdown锛屼篃涓嶈鍦ㄥ墠鍚庤拷鍔犺В閲婃枃鏈��
 4. 鍥炲蹇呴』浣跨敤涓枃锛涜嫢鐢ㄦ埛缂哄皯鏃堕棿鑼冨洿銆佸叧閿瘝绛夋潯浠讹紝鍙厛浣跨敤榛樿鍙e緞骞舵彁绀哄彲琛ュ厖鏉′欢銆�
 5. 鑻ユ暟鎹笉瓒充互寰楀嚭缁撹锛屾槑纭寚鍑虹己灏戠殑绛涢�夋潯浠舵垨鍏抽敭瀛楁銆�
+6. 鐢ㄦ埛鎻愬埌鈥滀粖骞�/鏈湀/浠婂ぉ/鏈�杩�/涓婃湀/鍘诲勾鈥濈瓑鐩稿鏃堕棿鏃讹紝蹇呴』涓ユ牸鍩轰簬鈥滃綋鍓嶆棩鏈熲�濇崲绠楋紝绂佹鑷鍋囪骞翠唤銆�

--
Gitblit v1.9.3