From 1c518e10a50050d383e714b581c94dea58ec4d67 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期五, 22 五月 2026 18:01:34 +0800
Subject: [PATCH] fix(approve): 修复审批实例查询条件及流程控制问题

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

diff --git a/src/main/java/com/ruoyi/ai/assistant/SalesIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/SalesIntentExecutor.java
new file mode 100644
index 0000000..4388a3c
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/assistant/SalesIntentExecutor.java
@@ -0,0 +1,270 @@
+package com.ruoyi.ai.assistant;
+
+import com.ruoyi.ai.tools.SalesAgentTools;
+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 SalesIntentExecutor {
+
+    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 final SalesAgentTools salesAgentTools;
+
+    public SalesIntentExecutor(SalesAgentTools salesAgentTools) {
+        this.salesAgentTools = salesAgentTools;
+    }
+
+    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;
+        }
+
+        String keyword = extractKeyword(text);
+        Integer limit = extractLimit(text);
+        DateRange dateRange = extractDateRange(text);
+        String startDate = dateRange.startDate();
+        String endDate = dateRange.endDate();
+
+        if (containsAny(text, "娴佸け", "娴佸け椋庨櫓", "瀹㈡埛娴佸け", "椋庨櫓鍒嗘瀽")) {
+            return salesAgentTools.analyzeCustomerChurnRisk(memoryId, startDate, endDate, text, keyword, limit);
+        }
+        if (containsAny(text, "鍥炴", "鏀舵", "鎶ヤ环")
+                && containsAny(text, "寤鸿", "绛栫暐", "浼樺寲", "鏂规")) {
+            return salesAgentTools.suggestCollectionAndQuotationStrategy(
+                    memoryId, startDate, endDate, text, keyword, limit, shouldPrioritizeHighRisk(text));
+        }
+        if (containsAny(text, "鎸囨爣", "缁熻", "鐪嬫澘", "鎬昏", "缁忚惀鍒嗘瀽")) {
+            return salesAgentTools.getSalesDashboard(memoryId, startDate, endDate, text);
+        }
+        if (containsAny(text, "瀹㈡埛妗f", "绉佹捣", "鍏捣", "瀹㈡埛姹�")) {
+            return salesAgentTools.listCustomerProfiles(memoryId, extractSeaType(text), keyword, limit);
+        }
+        if (containsAny(text, "閿�鍞姤浠�", "鎶ヤ环鍗�", "鎶ヤ环", "璇环")) {
+            return salesAgentTools.listSalesQuotations(memoryId, keyword, startDate, endDate, limit);
+        }
+        if (containsAny(text, "閿�鍞��璐�", "閫�璐�", "閫�娆�")) {
+            return salesAgentTools.listSalesReturns(memoryId, startDate, endDate, keyword, limit);
+        }
+        if (containsAny(text, "瀹㈡埛寰�鏉�", "寰�鏉�", "鍥炴", "搴旀敹", "鏉ユ", "鏀舵鏄庣粏")) {
+            return salesAgentTools.listCustomerInteractions(memoryId, keyword, startDate, endDate, limit);
+        }
+        if (containsAny(text, "鍙戣揣鍙拌处", "鍙戣揣", "鐗╂祦", "蹇��", "杩愯緭")) {
+            return salesAgentTools.listShippingLedgers(memoryId, keyword, startDate, endDate, limit);
+        }
+        if (containsAny(text, "閿�鍞彴璐�", "閿�鍞悎鍚�", "閿�鍞鍗�", "鍚堝悓鍙拌处", "璁㈠崟鍙拌处")) {
+            return salesAgentTools.listSalesLedgers(memoryId, keyword, startDate, endDate, limit);
+        }
+        return null;
+    }
+
+    private String tryExecuteQuickPrompt(String memoryId, String text) {
+        String normalized = normalizeForMatch(text);
+        if ("鏌ヨ绉佹捣瀹㈡埛妗f鍓�10鏉�".equals(normalized)) {
+            return salesAgentTools.listCustomerProfiles(memoryId, "private", null, 10);
+        }
+        if ("鏌ヨ鍏捣瀹㈡埛妗f".equals(normalized)) {
+            return salesAgentTools.listCustomerProfiles(memoryId, "public", null, 10);
+        }
+        if ("鏌ヨ鏈湀閿�鍞姤浠�".equals(normalized)) {
+            DateRange range = monthRange();
+            return salesAgentTools.listSalesQuotations(memoryId, null, range.startDate(), range.endDate(), 10);
+        }
+        if ("鏌ヨ鏈湀閿�鍞彴璐�".equals(normalized)) {
+            DateRange range = monthRange();
+            return salesAgentTools.listSalesLedgers(memoryId, null, range.startDate(), range.endDate(), 10);
+        }
+        if ("鏌ヨ杩�30澶╅攢鍞��璐�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return salesAgentTools.listSalesReturns(memoryId, range.startDate(), range.endDate(), null, 10);
+        }
+        if ("鏌ヨ杩�30澶╁鎴峰洖娆惧線鏉�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return salesAgentTools.listCustomerInteractions(memoryId, null, range.startDate(), range.endDate(), 10);
+        }
+        if ("鏌ヨ鏈湀鍙戣揣鍙拌处".equals(normalized)) {
+            DateRange range = monthRange();
+            return salesAgentTools.listShippingLedgers(memoryId, null, range.startDate(), range.endDate(), 10);
+        }
+        if ("鏌ョ湅閿�鍞寚鏍囩粺璁�".equals(normalized)) {
+            return salesAgentTools.getSalesDashboard(memoryId, null, null, "鏈湀");
+        }
+        if ("甯垜鍋氬鎴锋祦澶遍闄╁垎鏋愯繎30澶╁墠20鏉�".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return salesAgentTools.analyzeCustomerChurnRisk(memoryId, range.startDate(), range.endDate(), "杩�30澶�", null, 20);
+        }
+        if ("鐢熸垚鍥炴涓庢姤浠风瓥鐣ュ缓璁紭鍏堥珮椋庨櫓瀹㈡埛".equals(normalized)) {
+            DateRange range = recentDaysRange(30);
+            return salesAgentTools.suggestCollectionAndQuotationStrategy(memoryId, range.startDate(), range.endDate(), "杩�30澶�", null, 10, true);
+        }
+        return null;
+    }
+
+    private boolean containsAny(String text, String... keywords) {
+        for (String keyword : keywords) {
+            if (text.contains(keyword)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String extractSeaType(String text) {
+        if (text.contains("鍏捣")) {
+            return "public";
+        }
+        if (text.contains("绉佹捣")) {
+            return "private";
+        }
+        return null;
+    }
+
+    private Integer extractLimit(String text) {
+        Matcher matcher = LIMIT_PATTERN.matcher(text);
+        return matcher.find() ? Integer.parseInt(matcher.group(2)) : 10;
+    }
+
+    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);
+        }
+        if (text.contains("鏈湀")) {
+            return monthRange();
+        }
+        if (text.contains("涓婃湀")) {
+            return lastMonthRange();
+        }
+        if (text.contains("鏈勾") || text.contains("浠婂勾")) {
+            return yearRange();
+        }
+        Matcher relativeDayMatcher = RELATIVE_DAY_PATTERN.matcher(text);
+        if (relativeDayMatcher.find()) {
+            int days = Integer.parseInt(relativeDayMatcher.group(2));
+            return recentDaysRange(days);
+        }
+        return new DateRange(null, null);
+    }
+
+    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 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));
+    }
+
+    private DateRange monthRange() {
+        LocalDate today = LocalDate.now();
+        return new DateRange(formatDate(today.withDayOfMonth(1)), 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(" ", "")
+                .trim();
+    }
+
+    private Boolean shouldPrioritizeHighRisk(String text) {
+        return containsAny(text, "浼樺厛楂橀闄�", "楂橀闄╁鎴�", "楂橀闄�");
+    }
+
+    private String extractKeyword(String text) {
+        String cleaned = text
+                .replace("鏌ヨ", "")
+                .replace("鏌ョ湅", "")
+                .replace("鐪嬩笅", "")
+                .replace("鐪嬬湅", "")
+                .replace("甯垜", "")
+                .replace("璇�", "")
+                .replace("涓�涓�", "")
+                .replace("閿�鍞�", "")
+                .replace("瀹㈡埛妗f", "")
+                .replace("鎶ヤ环鍗�", "")
+                .replace("閿�鍞姤浠�", "")
+                .replace("閿�鍞彴璐�", "")
+                .replace("鍙戣揣鍙拌处", "")
+                .replace("瀹㈡埛寰�鏉�", "")
+                .replace("閿�鍞��璐�", "")
+                .replace("鍓�10鏉�", "")
+                .replace("鏈�杩�10鏉�", "")
+                .replace("鍓�20鏉�", "")
+                .replace("鏈�杩�20鏉�", "")
+                .replace("杩�30澶�", "")
+                .replace("鏈湀", "")
+                .replace("鏈勾", "")
+                .replace("浠婂勾", "")
+                .replace("鏉�", "")
+                .trim();
+        return cleaned.length() >= 2 ? cleaned : null;
+    }
+
+    private record DateRange(String startDate, String endDate) {
+    }
+}

--
Gitblit v1.9.3