From bdee3858f95d92cb20514a8525f39d1f304876f8 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 18 五月 2026 14:56:43 +0800
Subject: [PATCH] config(zxsq): 更新配置文件以支持个推推送、MongoDB存储和文件上传功能

---
 src/main/java/com/ruoyi/ai/tools/ApproveTodoTools.java              |   17 +++
 src/main/java/com/ruoyi/ai/controller/XiaozhiController.java        |   31 ++++++
 src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java |  199 +++++++++++++++++++++++++++++++++++----
 3 files changed, 223 insertions(+), 24 deletions(-)

diff --git a/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java
index 9f8499d..8d8ad45 100644
--- a/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java
+++ b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java
@@ -14,8 +14,9 @@
 @Component
 public class ApproveTodoIntentExecutor {
 
-    private static final Pattern APPROVE_ID_PATTERN = Pattern.compile("\\b[A-Za-z]*\\d{8,}\\b");
-    private static final Pattern LIMIT_PATTERN = Pattern.compile("(鍓峾鏈�杩�)?(\\d{1,2})鏉�");
+    private static final Pattern APPROVE_ID_BY_LABEL_PATTERN = Pattern.compile("(娴佺▼缂栧彿|娴佺▼鍙穦娴佺▼ID|瀹℃壒缂栧彿|缂栧彿)\\s*[:锛歖?\\s*([A-Za-z0-9_-]{2,64})");
+    private static final Pattern APPROVE_ID_PATTERN = Pattern.compile("\\b[A-Za-z]*\\d{6,}[A-Za-z0-9_-]*\\b");
+    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 NUMBER_PATTERN = Pattern.compile("(\\d+(?:\\.\\d+)?)");
     private static final Pattern RECENT_RANGE_PATTERN = Pattern.compile("杩慭\d+(澶﹟鍛▅涓湀|鏈坾骞�)");
@@ -34,54 +35,63 @@
         }
 
         String text = message.trim();
+        String quickPromptResponse = tryExecuteQuickPrompt(memoryId, text);
+        if (StringUtils.hasText(quickPromptResponse)) {
+            return quickPromptResponse;
+        }
+
         String approveId = extractApproveId(text);
+        boolean hasApproveId = StringUtils.hasText(approveId) && !isPlaceholderApproveId(approveId);
+        String startDate = extractStartDate(text);
+        String endDate = extractEndDate(text);
+        String timeRange = extractTimeRange(text);
 
         if (isStatsIntent(text)) {
             return approveTodoTools.getTodoStats(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractTimeRange(text)
+                    startDate,
+                    endDate,
+                    timeRange
             );
         }
         if (containsAny(text, "娴佽浆", "杩涘害", "鑺傜偣", "鏃ュ織", "鍗″湪", "鍗″埌", "褰撳墠瀹℃壒浜�", "澶勭悊璁板綍")) {
-            return StringUtils.hasText(approveId)
+            return hasApproveId
                     ? approveTodoTools.getTodoProgress(memoryId, approveId)
                     : missingApproveId("todo_progress", "鏌ヨ瀹℃壒杩涘害闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
         if (containsAny(text, "璇︽儏", "鏄庣粏") && !containsAny(text, "鍒楄〃")) {
-            return StringUtils.hasText(approveId)
+            return hasApproveId
                     ? approveTodoTools.getTodoDetail(memoryId, approveId)
                     : missingApproveId("todo_detail", "鏌ヨ瀹℃壒璇︽儏闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
         if (containsAny(text, "鍙栨秷瀹℃牳", "鎾ら攢瀹℃牳", "鍥為��瀹℃牳", "鎾ら攢瀹℃壒", "鎾ゅ洖瀹℃壒")
                 || (containsAny(text, "鎾ら攢", "鎾ゅ洖") && containsAny(text, "瀹℃壒鎿嶄綔", "瀹℃牳鎿嶄綔"))) {
-            return StringUtils.hasText(approveId)
-                    ? approveTodoTools.cancelReviewTodo(memoryId, approveId, firstNonBlank(extractTail(text, "鍘熷洜"), extractTail(text, "澶囨敞")))
+            return hasApproveId
+                    ? approveTodoTools.cancelReviewTodo(memoryId, approveId, extractRemark(text))
                     : missingApproveId("cancel_review_action", "鍙栨秷瀹℃牳闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
         if (containsAny(text, "鍒犻櫎", "绉婚櫎")) {
-            return StringUtils.hasText(approveId)
+            return hasApproveId
                     ? approveTodoTools.deleteTodo(memoryId, approveId)
                     : missingApproveId("delete_action", "鍒犻櫎瀹℃壒鍗曢渶瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
         if (containsAny(text, "椹冲洖", "鎷掔粷")) {
-            return StringUtils.hasText(approveId)
-                    ? approveTodoTools.reviewTodo(memoryId, approveId, "reject", firstNonBlank(extractTail(text, "鍘熷洜"), extractTail(text, "澶囨敞")))
+            return hasApproveId
+                    ? approveTodoTools.reviewTodo(memoryId, approveId, "reject", extractRemark(text))
                     : missingApproveId("review_action", "椹冲洖瀹℃壒闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
         if (containsAny(text, "瀹℃牳閫氳繃", "瀹℃壒閫氳繃", "閫氳繃瀹℃壒", "鍚屾剰瀹℃壒", "瀹℃壒鍚屾剰")) {
-            return StringUtils.hasText(approveId)
-                    ? approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractTail(text, "澶囨敞"))
+            return hasApproveId
+                    ? approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractRemark(text))
                     : missingApproveId("review_action", "瀹℃壒閫氳繃闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
         }
-        if (StringUtils.hasText(approveId)
+        if (hasApproveId
                 && containsAny(text, "閫氳繃", "鍚屾剰")
                 && !containsAny(text, "鏈�氳繃", "閫氳繃鐜�", "瀹℃壒閫氳繃鐜�", "瀹℃牳閫氳繃鐜�")) {
-            return approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractTail(text, "澶囨敞"));
+            return approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractRemark(text));
         }
         if (containsAny(text, "淇敼", "鏇存柊", "鍙樻洿")) {
-            return StringUtils.hasText(approveId)
+            return hasApproveId
                     ? approveTodoTools.updateTodo(
                     memoryId,
                     approveId,
@@ -101,7 +111,82 @@
                     extractApproveType(text),
                     extractKeyword(text),
                     extractLimit(text),
-                    extractScope(text));
+                    extractScope(text),
+                    startDate,
+                    endDate,
+                    timeRange);
+        }
+        return null;
+    }
+
+    private String tryExecuteQuickPrompt(String memoryId, String text) {
+        String normalized = normalizeForMatch(text);
+        String approveId = extractApproveId(text);
+        boolean hasApproveId = StringUtils.hasText(approveId) && !isPlaceholderApproveId(approveId);
+
+        if ("鎴戝綋鍓嶆湁鍝簺瀹℃壒寰呭姙闇�瑕佸鐞�".equals(normalized)) {
+            return approveTodoTools.listTodos(memoryId, "pending", null, null, 10, "approver", null, null, null);
+        }
+        if ("甯垜鍒楀嚭浠婂ぉ鏂板鐨勫鎵瑰緟鍔�".equals(normalized)) {
+            return approveTodoTools.listTodos(memoryId, "all", null, null, 10, "related", null, null, "浠婂ぉ");
+        }
+        if ("褰撳墠寰呮垜瀹℃壒鐨勫崟鎹寜鏃堕棿鍊掑簭鍒楀嚭鏉�".equals(normalized)) {
+            return approveTodoTools.listTodos(memoryId, "pending", null, null, 10, "approver", null, null, null);
+        }
+        if ("鎴戝彂璧风殑瀹℃壒閲屽摢浜涜繕鍦ㄥ鐞嗕腑".equals(normalized)) {
+            return approveTodoTools.listTodos(memoryId, "processing", null, null, 10, "applicant", null, null, null);
+        }
+        if ("杩�7澶╂垜鐨勫鎵瑰緟鍔炵粺璁℃儏鍐垫�庝箞鏍�".equals(normalized)) {
+            return approveTodoTools.getTodoStats(memoryId, null, null, "杩�7澶�");
+        }
+        if ("鏈湀鎴戠殑瀹℃壒涓�氳繃椹冲洖澶勭悊涓悇鏈夊灏�".equals(normalized)) {
+            return approveTodoTools.getTodoStats(memoryId, null, null, "鏈湀");
+        }
+        if ("杩�30澶╁悇绫诲瀷瀹℃壒鏁伴噺鍒嗗竷鏄粈涔�".equals(normalized)) {
+            return approveTodoTools.getTodoStats(memoryId, null, null, "杩�30澶�");
+        }
+
+        if (normalized.startsWith("鏌ヨ娴佺▼缂栧彿") && normalized.contains("瀹℃壒璇︽儏")) {
+            return hasApproveId
+                    ? approveTodoTools.getTodoDetail(memoryId, approveId)
+                    : missingApproveId("todo_detail", "鏌ヨ瀹℃壒璇︽儏闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("娴佺▼缂栧彿")
+                && normalized.contains("鍗″湪鍝釜瀹℃壒鑺傜偣")
+                && normalized.contains("褰撳墠瀹℃壒浜烘槸璋�")) {
+            return hasApproveId
+                    ? approveTodoTools.getTodoProgress(memoryId, approveId)
+                    : missingApproveId("todo_progress", "鏌ヨ瀹℃壒杩涘害闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("甯垜鏌ョ湅娴佺▼缂栧彿") && normalized.contains("瀹℃壒娴佽浆璁板綍")) {
+            return hasApproveId
+                    ? approveTodoTools.getTodoProgress(memoryId, approveId)
+                    : missingApproveId("todo_progress", "鏌ヨ瀹℃壒娴佽浆璁板綍闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("甯垜瀹℃壒閫氳繃娴佺▼缂栧彿")) {
+            return hasApproveId
+                    ? approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractRemark(text))
+                    : missingApproveId("review_action", "瀹℃壒閫氳繃闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("甯垜椹冲洖娴佺▼缂栧彿")) {
+            return hasApproveId
+                    ? approveTodoTools.reviewTodo(memoryId, approveId, "reject", extractRemark(text))
+                    : missingApproveId("review_action", "椹冲洖瀹℃壒闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("鎾ら攢鎴戝垰鍒氬娴佺▼缂栧彿") && normalized.contains("瀹℃壒鎿嶄綔")) {
+            return hasApproveId
+                    ? approveTodoTools.cancelReviewTodo(memoryId, approveId, extractRemark(text))
+                    : missingApproveId("cancel_review_action", "鎾ら攢瀹℃壒鎿嶄綔闇�瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("甯垜淇敼娴佺▼缂栧彿") && normalized.contains("澶囨敞涓�")) {
+            return hasApproveId
+                    ? approveTodoTools.updateTodo(memoryId, approveId, null, null, null, null, null, null, extractRemark(text))
+                    : missingApproveId("update_action", "淇敼瀹℃壒鍗曢渶瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
+        }
+        if (normalized.startsWith("鍒犻櫎鎴戝彂璧风殑娴佺▼缂栧彿")) {
+            return hasApproveId
+                    ? approveTodoTools.deleteTodo(memoryId, approveId)
+                    : missingApproveId("delete_action", "鍒犻櫎瀹℃壒鍗曢渶瑕佹彁渚涚湡瀹炴祦绋嬬紪鍙枫��");
         }
         return null;
     }
@@ -130,6 +215,10 @@
     }
 
     private String extractApproveId(String text) {
+        Matcher keywordMatcher = APPROVE_ID_BY_LABEL_PATTERN.matcher(text);
+        if (keywordMatcher.find()) {
+            return keywordMatcher.group(2);
+        }
         Matcher matcher = APPROVE_ID_PATTERN.matcher(text);
         return matcher.find() ? matcher.group() : null;
     }
@@ -196,6 +285,8 @@
                 .replace("鍗曟嵁", "")
                 .replace("寰呭姙", "")
                 .replace("鍒楄〃", "")
+                .replace("娴佺▼缂栧彿", "")
+                .replace("娴佺▼鍙�", "")
                 .replace("鍓�10鏉�", "")
                 .replace("鏈�杩�10鏉�", "")
                 .trim();
@@ -203,7 +294,7 @@
     }
 
     private String extractValue(String text, String fieldName) {
-        Pattern pattern = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗鏄�)[:锛歖?[\\s]*([^,锛屻�傦紱;\\s]+)");
+        Pattern pattern = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗涓簗鏄�)[:锛歖?[\\s]*([^,锛屻�傦紱;\\s]+)");
         Matcher matcher = pattern.matcher(text);
         return matcher.find() ? matcher.group(2) : null;
     }
@@ -250,7 +341,7 @@
         if (!text.contains(fieldName)) {
             return null;
         }
-        Matcher matcher = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗鏄�)[:锛歖?[\\s]*(\\d{1,2})").matcher(text);
+        Matcher matcher = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗涓簗鏄�)[:锛歖?[\\s]*(\\d{1,2})").matcher(text);
         return matcher.find() ? Integer.parseInt(matcher.group(2)) : null;
     }
 
@@ -264,21 +355,85 @@
     }
 
     private String extractTail(String text, String key) {
+        Pattern quotedPattern = Pattern.compile(key + "(鏄瘄涓�)?[:锛歖?[\\s]*[鈥淺"]([^鈥漒"]+)[鈥漒"]");
+        Matcher quotedMatcher = quotedPattern.matcher(text);
+        if (quotedMatcher.find()) {
+            return cleanContent(quotedMatcher.group(2));
+        }
         Pattern pattern = Pattern.compile(key + "(鏄瘄涓�)?[:锛歖?[\\s]*(.+)");
         Matcher matcher = pattern.matcher(text);
-        return matcher.find() ? matcher.group(2).trim() : null;
+        return matcher.find() ? cleanContent(matcher.group(2)) : null;
     }
 
     private String extractScope(String text) {
         if (containsAny(text, "鎴戝彂璧�", "鎴戞彁浜�", "鎴戠敵璇�", "鐢宠浜烘槸鎴�")) {
             return "applicant";
         }
-        if (containsAny(text, "寰呮垜瀹℃壒", "寰呮垜瀹℃牳", "鎴戝鐞�", "鎴戝鎵�", "褰撳墠寰呮垜", "闇�瑕佹垜澶勭悊")) {
+        if (containsAny(text, "寰呮垜瀹℃壒", "寰呮垜瀹℃牳", "鎴戝鐞�", "鎴戝鎵�", "褰撳墠寰呮垜", "闇�瑕佹垜澶勭悊", "闇�瑕佸鐞�")) {
             return "approver";
         }
         return "related";
     }
 
+    private String extractRemark(String text) {
+        return firstNonBlank(firstNonBlank(extractTail(text, "澶囨敞"), extractTail(text, "鍘熷洜")), extractQuotedContent(text));
+    }
+
+    private String extractQuotedContent(String text) {
+        Matcher matcher = Pattern.compile("[鈥淺"]([^鈥漒"]+)[鈥漒"]").matcher(text);
+        return matcher.find() ? cleanContent(matcher.group(1)) : null;
+    }
+
+    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("鈥�", "")
+                .replace("鈥�", "")
+                .replace("\"", "")
+                .replace(" ", "")
+                .trim();
+    }
+
+    private boolean isPlaceholderApproveId(String approveId) {
+        if (!StringUtils.hasText(approveId)) {
+            return true;
+        }
+        String value = approveId.trim();
+        return "xxx".equalsIgnoreCase(value)
+                || value.matches("[xX]{2,}")
+                || "娴佺▼缂栧彿".equals(value)
+                || "缂栧彿".equals(value)
+                || value.contains("绀轰緥")
+                || value.contains("璇疯緭鍏�");
+    }
+
+    private String cleanContent(String text) {
+        if (!StringUtils.hasText(text)) {
+            return null;
+        }
+        return text.trim()
+                .replace("鈥�", "")
+                .replace("鈥�", "")
+                .replace("\"", "")
+                .replace("銆�", "")
+                .replace("锛�", "")
+                .replace(";", "")
+                .trim();
+    }
+
     private String firstNonBlank(String first, String second) {
         return StringUtils.hasText(first) ? first : second;
     }
diff --git a/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java b/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
index eac43b2..affa347 100644
--- a/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
+++ b/src/main/java/com/ruoyi/ai/controller/XiaozhiController.java
@@ -90,6 +90,16 @@
             return Flux.just(directResponse);
         }
 
+        if (isApproveTodoBusinessIntent(userMessage)) {
+            String noGuessResponse = "鏈瘑鍒埌鍙墽琛岀殑瀹℃壒寰呭姙鎿嶄綔鏉′欢銆備负淇濊瘉缁撴灉鍑嗙‘锛屽綋鍓嶄笉浼氭帹娴嬫垨缂栭�犲鎵规暟鎹紝璇疯ˉ鍏呮祦绋嬬紪鍙枫�佹椂闂磋寖鍥存垨鏄庣‘鎿嶄綔鎸囦护鍚庡啀璇曘��";
+            mongoChatMemoryStore.appendMessages(
+                    memoryId,
+                    List.of(UserMessage.from(userMessage), AiMessage.from(noGuessResponse))
+            );
+            aiChatSessionService.refreshSessionStats(memoryId, loginUser);
+            return Flux.just(noGuessResponse);
+        }
+
         return approveTodoAgent.chat(memoryId, userMessage)
                 .doOnComplete(() -> aiChatSessionService.refreshSessionStats(memoryId, loginUser))
                 .doOnError(ex -> aiChatSessionService.refreshSessionStats(memoryId, loginUser));
@@ -159,4 +169,25 @@
         aiSessionUserContext.remove(memoryId);
         return toAjax(aiChatSessionService.deleteCurrentUserSession(memoryId, SecurityUtils.getLoginUser()));
     }
+
+    private boolean isApproveTodoBusinessIntent(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;
+    }
 }
diff --git a/src/main/java/com/ruoyi/ai/tools/ApproveTodoTools.java b/src/main/java/com/ruoyi/ai/tools/ApproveTodoTools.java
index cd3e933..fec0c21 100644
--- a/src/main/java/com/ruoyi/ai/tools/ApproveTodoTools.java
+++ b/src/main/java/com/ruoyi/ai/tools/ApproveTodoTools.java
@@ -76,12 +76,17 @@
                             @P(value = "瀹℃壒绫诲瀷缂栧彿锛屽彲涓嶄紶", required = false) Integer approveType,
                             @P(value = "鍏抽敭瀛楋紝鍙尮閰嶆祦绋嬬紪鍙枫�佹爣棰樸�佺敵璇蜂汉銆佸綋鍓嶅鎵逛汉", required = false) String keyword,
                             @P(value = "杩斿洖鏉℃暟锛岄粯璁�10锛屾渶澶�20", required = false) Integer limit,
-                            @P(value = "鏌ヨ鑼冨洿锛屽彲閫夊�硷細related銆乤pplicant銆乤pprover锛況elated 琛ㄧず褰撳墠鐢ㄦ埛鐩稿叧锛宎pplicant 琛ㄧず鎴戝彂璧风殑锛宎pprover 琛ㄧず寰呮垜澶勭悊鐨�", required = false) String scope) {
+                            @P(value = "鏌ヨ鑼冨洿锛屽彲閫夊�硷細related銆乤pplicant銆乤pprover锛況elated 琛ㄧず褰撳墠鐢ㄦ埛鐩稿叧锛宎pplicant 琛ㄧず鎴戝彂璧风殑锛宎pprover 琛ㄧず寰呮垜澶勭悊鐨�", required = false) String scope,
+                            @P(value = "寮�濮嬫棩鏈� yyyy-MM-dd锛屽彲涓嶄紶", required = false) String startDate,
+                            @P(value = "缁撴潫鏃ユ湡 yyyy-MM-dd锛屽彲涓嶄紶", required = false) String endDate,
+                            @P(value = "鏃堕棿鑼冨洿鎻忚堪锛屼緥濡� 浠婂ぉ銆佹湰鏈堛�佽繎30澶╋紝鍙笉浼�", required = false) String timeRange) {
 
         LoginUser loginUser = currentLoginUser(memoryId);
         Long userId = loginUser.getUserId();
         Integer statusCode = parseStatus(status);
         String normalizedScope = normalizeScope(scope);
+        boolean hasDateFilter = StringUtils.hasText(startDate) || StringUtils.hasText(endDate) || StringUtils.hasText(timeRange);
+        DateRange dateRange = hasDateFilter ? resolveDateRange(startDate, endDate, timeRange) : null;
 
         LambdaQueryWrapper<ApproveProcess> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(ApproveProcess::getApproveDelete, 0);
@@ -120,6 +125,11 @@
             }
         }
 
+        if (dateRange != null) {
+            wrapper.ge(ApproveProcess::getCreateTime, dateRange.start().atStartOfDay())
+                    .lt(ApproveProcess::getCreateTime, dateRange.end().plusDays(1).atStartOfDay());
+        }
+
         wrapper.orderByDesc(ApproveProcess::getCreateTime)
                 .last("limit " + normalizeLimit(limit));
 
@@ -156,7 +166,10 @@
                         "statusFilter", StringUtils.hasText(status) ? status : "all",
                         "approveType", approveType == null ? "" : approveType,
                         "keyword", keyword == null ? "" : keyword,
-                        "scope", normalizedScope
+                        "scope", normalizedScope,
+                        "timeRange", dateRange == null ? "all" : dateRange.label(),
+                        "startDate", dateRange == null ? "" : dateRange.start().toString(),
+                        "endDate", dateRange == null ? "" : dateRange.end().toString()
                 ),
                 Map.of("columns", todoColumns(), "items", items),
                 Map.of());

--
Gitblit v1.9.3