15 小时以前 261a7d2645877369a8928d573e0fa0d978577ef3
src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
@@ -14,9 +14,10 @@
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 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 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;
@@ -42,18 +43,18 @@
        String endDate = dateRange.endDate();
        String timeRange = dateRange.label();
        if (containsAny(text, "成本核算", "产品成本", "工序成本", "人工成本", "折旧", "材料损耗")) {
        if (containsAny(text, "成本核算", "产品成本", "工序成本", "人工成本", "折旧", "材料损耗", "成本最高")) {
            return financialAgentTools.calculateIntelligentCost(memoryId, startDate, endDate, timeRange, keyword, limit);
        }
        if (containsAny(text, "利润分析", "订单利润", "亏损订单", "低利润",
                "最赚钱客户", "哪个客户最赚钱", "客户最赚钱", "利润最高客户", "利润贡献最高客户", "利润下降")) {
        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, limit);
            return financialAgentTools.forecastCashFlow(memoryId, startDate, endDate, timeRange, extractForecastMonths(text));
        }
        if (containsAny(text, "异常预警", "经营异常", "风险预警", "成本异常", "利润异常", "回款异常", "订单风险")) {
            return financialAgentTools.detectBusinessAnomalies(memoryId, startDate, endDate, timeRange, limit);
@@ -73,30 +74,35 @@
    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) || "哪个订单亏损".equals(normalized)) {
        if ("查询近30天亏损订单".equals(normalized)) {
            DateRange range = recentDaysRange(30);
            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, 20);
            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
        }
        if ("生成本周经营周报".equals(normalized) || "生成周报".equals(normalized)) {
            DateRange range = weekRange();
            return financialAgentTools.generateOperationReport(memoryId, range.startDate(), range.endDate(), range.label(), "weekly");
        if ("分析近30天库存资金占用".equals(normalized)) {
            DateRange range = recentDaysRange(30);
            return financialAgentTools.analyzeInventoryCapital(memoryId, range.startDate(), range.endDate(), range.label(), null, null);
        }
        if ("为什么利润下降".equals(normalized)) {
            DateRange range = monthRange();
            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, 20);
        if ("预测未来3个月现金流".equals(normalized)) {
            return financialAgentTools.forecastCashFlow(memoryId, null, null, null, 3);
        }
        if ("哪个客户最赚钱".equals(normalized)
                || "最近哪个客户最赚钱".equals(normalized)
                || "本月哪个客户最赚钱".equals(normalized)
                || "近30天哪个客户最赚钱".equals(normalized)
                || "哪个客户利润最高".equals(normalized)
                || "哪个客户利润贡献最高".equals(normalized)) {
            DateRange range = extractDateRange(text);
            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, 20);
        if ("哪个工序成本最高".equals(normalized)) {
            return financialAgentTools.calculateIntelligentCost(memoryId, null, null, null, null, null);
        }
        return null;
    }
@@ -112,7 +118,12 @@
    private Integer extractLimit(String text) {
        Matcher matcher = LIMIT_PATTERN.matcher(text);
        return matcher.find() ? Integer.parseInt(matcher.group(2)) : 10;
        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) {
@@ -128,7 +139,7 @@
        if (text.contains("上月")) {
            return lastMonthRange();
        }
        if (text.contains("本年") || text.contains("今年")) {
        if (text.contains("今年") || text.contains("本年")) {
            return yearRange();
        }
        if (text.contains("本周")) {
@@ -136,17 +147,17 @@
        }
        Matcher relativeDayMatcher = RELATIVE_DAY_PATTERN.matcher(text);
        if (relativeDayMatcher.find()) {
            int days = Integer.parseInt(relativeDayMatcher.group(2));
            int days = Integer.parseInt(relativeDayMatcher.group(1));
            return recentDaysRange(days);
        }
        return new DateRange(null, null, "近30天");
        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, "近30天");
            return new DateRange(null, null, null);
        }
        if (startDate.isAfter(endDate)) {
            LocalDate temp = startDate;
@@ -200,7 +211,11 @@
        if (!StringUtils.hasText(text)) {
            return "";
        }
        return text.replace(",", "")
        return text.replace("(", "")
                .replace(")", "")
                .replace("(", "")
                .replace(")", "")
                .replace(",", "")
                .replace(",", "")
                .replace("。", "")
                .replace(".", "")
@@ -218,13 +233,16 @@
    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("最近哪个客户最赚钱", "")