From 482b2982ba27b18e6391c3862ec239c89a801a46 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 21 五月 2026 13:09:05 +0800
Subject: [PATCH] feat(home): 添加生产看板功能并优化订单查询性能

---
 src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java |  144 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 122 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
index 5991fc3..802cc13 100644
--- a/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
+++ b/src/main/java/com/ruoyi/ai/assistant/PurchaseIntentExecutor.java
@@ -4,6 +4,10 @@
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -13,6 +17,8 @@
     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 RELATIVE_RANGE_PATTERN = Pattern.compile("(杩憒鏈�杩�)(\\d+)(澶﹟鍛▅涓湀|鏈坾骞�)");
+    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
     private final PurchaseAgentTools purchaseAgentTools;
 
@@ -25,57 +31,60 @@
             return null;
         }
         String text = message.trim();
+        String startDate = extractStartDate(text);
+        String endDate = extractEndDate(text);
+        Integer limit = extractLimit(text);
 
         if (containsAny(text, "鎺掕", "鎺掑悕", "鍓嶅嚑", "鍓嶄簲", "鍓嶅崄") && containsAny(text, "鐗╂枡", "浜у搧", "鍘熸潗鏂�", "閲囪喘閲戦", "閲戦")) {
             return purchaseAgentTools.rankPurchaseMaterials(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     text,
-                    extractLimit(text)
+                    limit
             );
         }
         if (containsAny(text, "鏈叆搴�", "寰呭叆搴�", "娌℃湁鍏ュ簱", "杩樻湭鍏ュ簱")) {
             return purchaseAgentTools.listUnstockedPurchaseOrders(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     extractKeyword(text),
-                    extractLimit(text)
+                    limit
             );
         }
         if (containsAny(text, "鍒拌揣寮傚父", "鍒拌揣鏈夊紓甯�", "寮傚父鍒拌揣", "鍒拌揣闂", "渚涘簲鍟嗗埌璐у紓甯�")) {
             return purchaseAgentTools.listArrivalExceptions(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     text,
-                    extractLimit(text)
+                    limit
             );
         }
         if (containsAny(text, "寰呬粯娆�", "鏈粯娆�", "鏈粯娓�", "寰呮敮浠�", "搴斾粯")) {
             return purchaseAgentTools.listPendingPaymentOrders(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     extractKeyword(text),
-                    extractLimit(text)
+                    limit
             );
         }
         if (containsAny(text, "閫�璐�", "閫�鏂�", "鎷掓敹")) {
             return purchaseAgentTools.listPurchaseReturns(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     extractKeyword(text),
-                    extractLimit(text)
+                    limit
             );
         }
         if (isStatsIntent(text)) {
             return purchaseAgentTools.getPurchaseStats(
                     memoryId,
-                    extractStartDate(text),
-                    extractEndDate(text),
+                    startDate,
+                    endDate,
                     text
             );
         }
@@ -86,9 +95,9 @@
             return purchaseAgentTools.listPurchaseLedgers(
                     memoryId,
                     extractKeyword(text),
-                    extractStartDate(text),
-                    extractEndDate(text),
-                    extractLimit(text)
+                    startDate,
+                    endDate,
+                    limit
             );
         }
         return null;
@@ -129,13 +138,18 @@
 
     private String extractStartDate(String text) {
         Matcher matcher = DATE_PATTERN.matcher(text);
-        return matcher.find() ? matcher.group() : null;
+        if (matcher.find()) {
+            return matcher.group();
+        }
+        DateRange range = extractRelativeDateRange(text);
+        return range == null ? null : range.start().format(DATE_FMT);
     }
 
     private String extractEndDate(String text) {
         Matcher matcher = DATE_PATTERN.matcher(text);
         if (!matcher.find()) {
-            return null;
+            DateRange range = extractRelativeDateRange(text);
+            return range == null ? null : range.end().format(DATE_FMT);
         }
         return matcher.find() ? matcher.group() : null;
     }
@@ -148,14 +162,100 @@
                 .replace("閲囪喘鍗�", "")
                 .replace("閲囪喘璁㈠崟", "")
                 .replace("璁㈠崟", "")
+                .replace("浠婂勾", "")
+                .replace("鏈勾", "")
+                .replace("鍘诲勾", "")
+                .replace("鏈湀", "")
+                .replace("涓婃湀", "")
+                .replace("鏈懆", "")
+                .replace("涓婂懆", "")
+                .replace("浠婂ぉ", "")
+                .replace("鏄ㄥぉ", "")
+                .replace("杩戝崐骞�", "")
+                .replace("鏈�杩戝崐骞�", "")
+                .replace("鏈�杩戝崐涓湀", "")
+                .replace("鍗婁釜鏈�", "")
                 .replace("鍙拌处", "")
                 .replace("鍒楄〃", "")
                 .replace("鍝簺", "")
+                .replace("浠�涔�", "")
+                .replace("鎯呭喌", "")
+                .replace("鏈夋病鏈�", "")
+                .replace("鏈夊暐", "")
+                .replace("鏈夋棤", "")
                 .replace("鍒楀嚭", "")
                 .replace("甯垜", "")
+                .replace("缁欐垜", "")
+                .replace("鎴�", "")
                 .replace("鏈�杩�10鏉�", "")
                 .replace("鍓�10鏉�", "")
                 .trim();
+        cleaned = DATE_PATTERN.matcher(cleaned).replaceAll("");
+        cleaned = RELATIVE_RANGE_PATTERN.matcher(cleaned).replaceAll("");
         return cleaned.length() >= 2 ? cleaned : null;
     }
+
+    private DateRange extractRelativeDateRange(String text) {
+        if (!StringUtils.hasText(text)) {
+            return null;
+        }
+        String normalized = text.toLowerCase(Locale.ROOT);
+        LocalDate today = LocalDate.now();
+
+        if (normalized.contains("浠婂ぉ")) {
+            return new DateRange(today, today);
+        }
+        if (normalized.contains("鏄ㄥぉ")) {
+            LocalDate yesterday = today.minusDays(1);
+            return new DateRange(yesterday, yesterday);
+        }
+        if (normalized.contains("浠婂勾") || normalized.contains("鏈勾")) {
+            return new DateRange(today.withDayOfYear(1), today);
+        }
+        if (normalized.contains("鍘诲勾")) {
+            LocalDate first = today.minusYears(1).withDayOfYear(1);
+            LocalDate last = first.withDayOfYear(first.lengthOfYear());
+            return new DateRange(first, last);
+        }
+        if (normalized.contains("鏈湀")) {
+            return new DateRange(today.withDayOfMonth(1), today);
+        }
+        if (normalized.contains("涓婃湀")) {
+            LocalDate first = today.minusMonths(1).withDayOfMonth(1);
+            LocalDate last = first.withDayOfMonth(first.lengthOfMonth());
+            return new DateRange(first, last);
+        }
+        if (normalized.contains("鏈懆")) {
+            LocalDate weekStart = today.with(DayOfWeek.MONDAY);
+            return new DateRange(weekStart, today);
+        }
+        if (normalized.contains("涓婂懆")) {
+            LocalDate weekStart = today.with(DayOfWeek.MONDAY).minusWeeks(1);
+            return new DateRange(weekStart, weekStart.plusDays(6));
+        }
+        if (normalized.contains("杩戝崐骞�") || normalized.contains("鏈�杩戝崐骞�")) {
+            return new DateRange(today.minusMonths(6).plusDays(1), today);
+        }
+        if (normalized.contains("杩戝崐涓湀") || normalized.contains("鏈�杩戝崐涓湀") || normalized.contains("鍗婁釜鏈�")) {
+            return new DateRange(today.minusDays(14), today);
+        }
+
+        Matcher matcher = RELATIVE_RANGE_PATTERN.matcher(normalized);
+        if (matcher.find()) {
+            int amount = Integer.parseInt(matcher.group(2));
+            String unit = matcher.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(start, today);
+        }
+        return null;
+    }
+
+    private record DateRange(LocalDate start, LocalDate end) {
+    }
 }

--
Gitblit v1.9.3