From 10b88a7ff17caf92f3d4e8a550c1085a70c2517a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 28 五月 2026 17:43:26 +0800
Subject: [PATCH] Merge dev_New_pro into dev_山西_晋和园_pro

---
 src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java |  284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 284 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
new file mode 100644
index 0000000..f402fc2
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
@@ -0,0 +1,284 @@
+package com.ruoyi.ai.assistant;
+
+import com.ruoyi.ai.tools.FinancialAgentTools;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Component
+public class FinancialIntentExecutor {
+
+    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    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_DAY_PATTERN = Pattern.compile("(?:杩憒鏈�杩�)\\s*(\\d{1,3})\\s*澶�");
+    private static final Pattern FUTURE_MONTH_PATTERN = Pattern.compile("(?:鏈潵|鍚庣画|鎺ヤ笅鏉�)\\s*(\\d{1,2})\\s*(?:涓�)?鏈�");
+
+    private final FinancialAgentTools financialAgentTools;
+
+    public FinancialIntentExecutor(FinancialAgentTools financialAgentTools) {
+        this.financialAgentTools = financialAgentTools;
+    }
+
+    public String tryExecute(String memoryId, String message) {
+        if (!StringUtils.hasText(message)) {
+            return null;
+        }
+        String text = message.trim();
+
+        String quickPromptResponse = tryExecuteQuickPrompt(memoryId, text);
+        if (StringUtils.hasText(quickPromptResponse)) {
+            return quickPromptResponse;
+        }
+
+        DateRange dateRange = extractDateRange(text);
+        Integer limit = extractLimit(text);
+        String keyword = extractKeyword(text);
+        String startDate = dateRange.startDate();
+        String endDate = dateRange.endDate();
+        String timeRange = dateRange.label();
+
+        if (containsAny(text, "鎴愭湰鏍哥畻", "浜у搧鎴愭湰", "宸ュ簭鎴愭湰", "浜哄伐鎴愭湰", "鎶樻棫", "鏉愭枡鎹熻��", "鎴愭湰鏈�楂�")) {
+            return financialAgentTools.calculateIntelligentCost(memoryId, startDate, endDate, timeRange, keyword, limit);
+        }
+        if (containsAny(text, "鍒╂鼎鍒嗘瀽", "璁㈠崟鍒╂鼎", "浜忔崯璁㈠崟", "浣庡埄娑�", "鏈�璧氶挶瀹㈡埛", "鍝釜瀹㈡埛鏈�璧氶挶",
+                "瀹㈡埛鏈�璧氶挶", "鍒╂鼎鏈�楂樺鎴�", "鍒╂鼎璐$尞鏈�楂�", "鍒╂鼎涓嬮檷")) {
+            return financialAgentTools.analyzeOrderProfit(memoryId, startDate, endDate, timeRange, keyword, limit);
+        }
+        if (containsAny(text, "搴撳瓨璧勯噾", "搴撳瓨绉帇", "鍛嗘粸搴撳瓨", "璧勯噾鍗犵敤", "鍛ㄨ浆鐜�", "搴撳瓨鍛ㄨ浆")) {
+            return financialAgentTools.analyzeInventoryCapital(memoryId, startDate, endDate, timeRange, keyword, limit);
+        }
+        if (containsAny(text, "鐜伴噾娴�", "鍥炴椋庨櫓", "浠樻鍘嬪姏", "璧勯噾缂哄彛", "搴旀敹", "搴斾粯", "鍥炴棰勬祴")) {
+            return financialAgentTools.forecastCashFlow(memoryId, startDate, endDate, timeRange, extractForecastMonths(text));
+        }
+        if (containsAny(text, "寮傚父棰勮", "缁忚惀寮傚父", "椋庨櫓棰勮", "鎴愭湰寮傚父", "鍒╂鼎寮傚父", "鍥炴寮傚父", "璁㈠崟椋庨櫓")) {
+            return financialAgentTools.detectBusinessAnomalies(memoryId, startDate, endDate, timeRange, limit);
+        }
+        if (containsAny(text, "椹鹃┒鑸�", "缁忚惀鐪嬫澘", "缁忚惀鎬昏", "缁忚惀浠〃鐩�", "缁忚惀澶х洏")) {
+            return financialAgentTools.getBusinessCockpit(memoryId, startDate, endDate, timeRange);
+        }
+        if (containsAny(text, "鏃ユ姤", "鍛ㄦ姤", "缁忚惀鎶ュ憡", "鍒嗘瀽鎶ュ憡")) {
+            return financialAgentTools.generateOperationReport(memoryId, startDate, endDate, timeRange,
+                    containsAny(text, "鍛ㄦ姤") ? "weekly" : "daily");
+        }
+        if (containsAny(text, "涓氳储铻嶅悎", "涓氳储鑱斿姩", "鍙e緞", "鎸囨爣瑙i噴", "涓轰粈涔�")) {
+            return financialAgentTools.retrieveFinancialKnowledge(memoryId, text);
+        }
+        return null;
+    }
+
+    private String tryExecuteQuickPrompt(String memoryId, String text) {
+        String normalized = normalizeForMatch(text);
+        if ("鐢熸垚鏈懆缁忚惀鍛ㄦ姤鍒╂鼎涓庣幇閲戞祦".equals(normalized) || "鐢熸垚鏈懆缁忚惀鍛ㄦ姤".equals(normalized) || "鐢熸垚鍛ㄦ姤".equals(normalized)) {
+            DateRange range = weekRange();
+            return financialAgentTools.generateOperationReport(memoryId, range.startDate(), range.endDate(), range.label(), "weekly");
+        }
+        if ("鍒嗘瀽鏈湀鍒╂鼎涓嬮檷鍘熷洜".equals(normalized)) {
+            DateRange range = monthRange();
+            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
+        }
+        if ("杩�30澶╁摢涓鎴峰埄娑﹁础鐚渶楂�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
+        }
+        if ("鏌ョ湅鏈湀缁忚惀椹鹃┒鑸�".equals(normalized) || "鏌ョ湅缁忚惀椹鹃┒鑸�".equals(normalized)) {
+            DateRange range = monthRange();
+            return financialAgentTools.getBusinessCockpit(memoryId, range.startDate(), range.endDate(), range.label());
+        }
+        if ("鏌ヨ杩�30澶╀簭鎹熻鍗�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
+        }
+        if ("鍒嗘瀽杩�30澶╁簱瀛樿祫閲戝崰鐢�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return financialAgentTools.analyzeInventoryCapital(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
+        }
+        if ("棰勬祴鏈潵3涓湀鐜伴噾娴�".equals(normalized)) {
+            return financialAgentTools.forecastCashFlow(memoryId, null, null, null, 3);
+        }
+        if ("鍝釜宸ュ簭鎴愭湰鏈�楂�".equals(normalized)) {
+            return financialAgentTools.calculateIntelligentCost(memoryId, null, null, null, null, null);
+        }
+        return null;
+    }
+
+    private boolean containsAny(String text, String... keywords) {
+        for (String keyword : keywords) {
+            if (text.contains(keyword)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Integer extractLimit(String text) {
+        Matcher matcher = LIMIT_PATTERN.matcher(text);
+        return matcher.find() ? Integer.parseInt(matcher.group(1)) : null;
+    }
+
+    private Integer extractForecastMonths(String text) {
+        Matcher matcher = FUTURE_MONTH_PATTERN.matcher(text);
+        return matcher.find() ? Integer.parseInt(matcher.group(1)) : null;
+    }
+
+    private DateRange extractDateRange(String text) {
+        Matcher matcher = DATE_PATTERN.matcher(text);
+        if (matcher.find()) {
+            String first = matcher.group(1);
+            String second = matcher.find() ? matcher.group(1) : first;
+            return buildDateRange(first, second, first + "鑷�" + second);
+        }
+        if (text.contains("鏈湀")) {
+            return monthRange();
+        }
+        if (text.contains("涓婃湀")) {
+            return lastMonthRange();
+        }
+        if (text.contains("浠婂勾") || text.contains("鏈勾")) {
+            return yearRange();
+        }
+        if (text.contains("鏈懆")) {
+            return weekRange();
+        }
+        Matcher relativeDayMatcher = RELATIVE_DAY_PATTERN.matcher(text);
+        if (relativeDayMatcher.find()) {
+            int days = Integer.parseInt(relativeDayMatcher.group(1));
+            return recentDaysRange(days);
+        }
+        return new DateRange(null, null, null);
+    }
+
+    private DateRange buildDateRange(String start, String end, String label) {
+        LocalDate startDate = parseDate(start);
+        LocalDate endDate = parseDate(end);
+        if (startDate == null || endDate == null) {
+            return new DateRange(null, null, null);
+        }
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+        return new DateRange(formatDate(startDate), formatDate(endDate), label);
+    }
+
+    private DateRange recentDaysRange(int days) {
+        LocalDate end = LocalDate.now();
+        int safeDays = Math.max(days, 1);
+        LocalDate start = end.minusDays(safeDays - 1L);
+        return new DateRange(formatDate(start), formatDate(end), "杩�" + safeDays + "澶�");
+    }
+
+    private DateRange monthRange() {
+        LocalDate today = LocalDate.now();
+        return new DateRange(formatDate(today.withDayOfMonth(1)), formatDate(today), "鏈湀");
+    }
+
+    private DateRange weekRange() {
+        LocalDate today = LocalDate.now();
+        LocalDate start = today.minusDays(today.getDayOfWeek().getValue() - 1L);
+        return new DateRange(formatDate(start), formatDate(today), "鏈懆");
+    }
+
+    private DateRange lastMonthRange() {
+        YearMonth lastMonth = YearMonth.now().minusMonths(1);
+        return new DateRange(formatDate(lastMonth.atDay(1)), formatDate(lastMonth.atEndOfMonth()), "涓婃湀");
+    }
+
+    private DateRange yearRange() {
+        LocalDate today = LocalDate.now();
+        return new DateRange(formatDate(today.withDayOfYear(1)), formatDate(today), "浠婂勾");
+    }
+
+    private LocalDate parseDate(String text) {
+        try {
+            return LocalDate.parse(text, DATE_FMT);
+        } catch (Exception ignored) {
+            return 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("锛�", "")
+                .replace(":", "")
+                .replace("锛�", "")
+                .replace(";", "")
+                .replace(" ", "")
+                .trim();
+    }
+
+    private String extractKeyword(String text) {
+        String cleaned = text
+                .replaceAll("\\d{4}-\\d{2}-\\d{2}", "")
+                .replaceAll("(?:杩憒鏈�杩�)\\s*\\d{1,3}\\s*澶�", "")
+                .replaceAll("(?:鍓峾鏈�杩憒灞曠ず|杩斿洖)?\\s*\\d{1,2}\\s*(?:鏉涓獆鍚�)", "")
+                .replace("鏌ヨ", "")
+                .replace("鏌ョ湅", "")
+                .replace("鐪嬩笅", "")
+                .replace("鐪嬬湅", "")
+                .replace("甯垜", "")
+                .replace("璇�", "")
+                .replace("涓�涓�", "")
+                .replace("涓轰粈涔�", "")
+                .replace("鍝釜瀹㈡埛鏈�璧氶挶", "")
+                .replace("鏈�杩戝摢涓鎴锋渶璧氶挶", "")
+                .replace("鏈湀鍝釜瀹㈡埛鏈�璧氶挶", "")
+                .replace("杩�30澶╁摢涓鎴锋渶璧氶挶", "")
+                .replace("鏈�璧氶挶瀹㈡埛", "")
+                .replace("瀹㈡埛鏈�璧氶挶", "")
+                .replace("鍝釜瀹㈡埛鍒╂鼎鏈�楂�", "")
+                .replace("鍒╂鼎鏈�楂樺鎴�", "")
+                .replace("鍝釜瀹㈡埛鍒╂鼎璐$尞鏈�楂�", "")
+                .replace("鍒╂鼎璐$尞鏈�楂樺鎴�", "")
+                .replace("鏈湀", "")
+                .replace("鏈懆", "")
+                .replace("鏈勾", "")
+                .replace("浠婂勾", "")
+                .replace("涓婃湀", "")
+                .replace("杩�30澶�", "")
+                .replace("杩�7澶�", "")
+                .replace("杩�90澶�", "")
+                .replace("鍓�10鏉�", "")
+                .replace("鏈�杩�10鏉�", "")
+                .replace("鍓�20鏉�", "")
+                .replace("鏈�杩�20鏉�", "")
+                .replace("璁㈠崟鍒╂鼎鍒嗘瀽", "")
+                .replace("鍒╂鼎鍒嗘瀽", "")
+                .replace("搴撳瓨璧勯噾鍒嗘瀽", "")
+                .replace("鐜伴噾娴侀娴�", "")
+                .replace("缁忚惀椹鹃┒鑸�", "")
+                .replace("鏃ユ姤", "")
+                .replace("鍛ㄦ姤", "")
+                .replace("寮傚父棰勮", "")
+                .replace("鏉�", "")
+                .trim();
+        return cleaned.length() >= 2 ? cleaned : null;
+    }
+
+    private record DateRange(String startDate, String endDate, String label) {
+    }
+}

--
Gitblit v1.9.3