From 1ca5584d7e3200a9af65a099bd26d3593e2ba702 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期四, 07 五月 2026 14:36:08 +0800
Subject: [PATCH] 迁移pro
---
src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 296 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java
new file mode 100644
index 0000000..9f8499d
--- /dev/null
+++ b/src/main/java/com/ruoyi/ai/assistant/ApproveTodoIntentExecutor.java
@@ -0,0 +1,296 @@
+package com.ruoyi.ai.assistant;
+
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.ai.tools.ApproveTodoTools;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@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 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+(澶﹟鍛▅涓湀|鏈坾骞�)");
+ private static final Pattern HALF_RANGE_PATTERN = Pattern.compile("(鏈�杩憒杩�)?鍗�(涓�)?(鏈坾骞�)");
+ private static final Pattern EXPLICIT_RANGE_PATTERN = Pattern.compile(".*(鍒皘鑷�).*");
+
+ private final ApproveTodoTools approveTodoTools;
+
+ public ApproveTodoIntentExecutor(ApproveTodoTools approveTodoTools) {
+ this.approveTodoTools = approveTodoTools;
+ }
+
+ public String tryExecute(String memoryId, String message) {
+ if (!StringUtils.hasText(message)) {
+ return null;
+ }
+
+ String text = message.trim();
+ String approveId = extractApproveId(text);
+
+ if (isStatsIntent(text)) {
+ return approveTodoTools.getTodoStats(
+ memoryId,
+ extractStartDate(text),
+ extractEndDate(text),
+ extractTimeRange(text)
+ );
+ }
+ if (containsAny(text, "娴佽浆", "杩涘害", "鑺傜偣", "鏃ュ織", "鍗″湪", "鍗″埌", "褰撳墠瀹℃壒浜�", "澶勭悊璁板綍")) {
+ return StringUtils.hasText(approveId)
+ ? approveTodoTools.getTodoProgress(memoryId, approveId)
+ : missingApproveId("todo_progress", "鏌ヨ瀹℃壒杩涘害闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (containsAny(text, "璇︽儏", "鏄庣粏") && !containsAny(text, "鍒楄〃")) {
+ return StringUtils.hasText(approveId)
+ ? 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, "澶囨敞")))
+ : missingApproveId("cancel_review_action", "鍙栨秷瀹℃牳闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (containsAny(text, "鍒犻櫎", "绉婚櫎")) {
+ return StringUtils.hasText(approveId)
+ ? approveTodoTools.deleteTodo(memoryId, approveId)
+ : missingApproveId("delete_action", "鍒犻櫎瀹℃壒鍗曢渶瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (containsAny(text, "椹冲洖", "鎷掔粷")) {
+ return StringUtils.hasText(approveId)
+ ? approveTodoTools.reviewTodo(memoryId, approveId, "reject", firstNonBlank(extractTail(text, "鍘熷洜"), extractTail(text, "澶囨敞")))
+ : missingApproveId("review_action", "椹冲洖瀹℃壒闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (containsAny(text, "瀹℃牳閫氳繃", "瀹℃壒閫氳繃", "閫氳繃瀹℃壒", "鍚屾剰瀹℃壒", "瀹℃壒鍚屾剰")) {
+ return StringUtils.hasText(approveId)
+ ? approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractTail(text, "澶囨敞"))
+ : missingApproveId("review_action", "瀹℃壒閫氳繃闇�瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (StringUtils.hasText(approveId)
+ && containsAny(text, "閫氳繃", "鍚屾剰")
+ && !containsAny(text, "鏈�氳繃", "閫氳繃鐜�", "瀹℃壒閫氳繃鐜�", "瀹℃牳閫氳繃鐜�")) {
+ return approveTodoTools.reviewTodo(memoryId, approveId, "approve", extractTail(text, "澶囨敞"));
+ }
+ if (containsAny(text, "淇敼", "鏇存柊", "鍙樻洿")) {
+ return StringUtils.hasText(approveId)
+ ? approveTodoTools.updateTodo(
+ memoryId,
+ approveId,
+ extractValue(text, "鏍囬"),
+ extractDateValue(text, "寮�濮嬫棩鏈�"),
+ extractDateValue(text, "缁撴潫鏃ユ湡"),
+ extractBigDecimalValue(text, "閲戦"),
+ extractValue(text, "鍦扮偣"),
+ extractIntegerValue(text, "绫诲瀷"),
+ extractValue(text, "澶囨敞"))
+ : missingApproveId("update_action", "淇敼瀹℃壒鍗曢渶瑕佹彁渚涙祦绋嬬紪鍙枫��");
+ }
+ if (containsAny(text, "鍒楄〃", "寰呭姙", "鏌ヨ瀹℃壒", "鍗曟嵁", "娴佺▼", "瀹℃壒鎵�")) {
+ return approveTodoTools.listTodos(
+ memoryId,
+ extractStatus(text),
+ extractApproveType(text),
+ extractKeyword(text),
+ extractLimit(text),
+ extractScope(text));
+ }
+ return null;
+ }
+
+ private boolean isStatsIntent(String text) {
+ if (containsAny(text, "缁熻", "鍒嗘瀽", "鍥捐〃", "瓒嬪娍", "鍗犳瘮", "姹囨��", "鎬婚噺", "鍒嗗竷", "鍚勬湁澶氬皯", "鏈夊灏�")) {
+ return true;
+ }
+ boolean hasQueryWord = containsAny(text, "鏌ヨ", "鏌ョ湅", "鐪嬩笅", "鐪嬬湅", "鑾峰彇");
+ boolean hasDataWord = containsAny(text, "鏁版嵁", "鎶ヨ〃", "鎯呭喌", "鏁伴噺", "閲戦");
+ boolean hasTimeWord = containsAny(text, "浠婂ぉ", "鏄ㄦ棩", "鏄ㄥぉ", "鏈懆", "涓婂懆", "鏈湀", "涓婃湀", "鏈勾", "浠婂勾", "鍘诲勾")
+ || DATE_PATTERN.matcher(text).find()
+ || RECENT_RANGE_PATTERN.matcher(text).find()
+ || HALF_RANGE_PATTERN.matcher(text).find()
+ || EXPLICIT_RANGE_PATTERN.matcher(text).matches();
+ return hasQueryWord && hasDataWord && hasTimeWord;
+ }
+
+ private boolean containsAny(String text, String... keywords) {
+ for (String keyword : keywords) {
+ if (text.contains(keyword)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String extractApproveId(String text) {
+ Matcher matcher = APPROVE_ID_PATTERN.matcher(text);
+ return matcher.find() ? matcher.group() : null;
+ }
+
+ private Integer extractLimit(String text) {
+ Matcher matcher = LIMIT_PATTERN.matcher(text);
+ return matcher.find() ? Integer.parseInt(matcher.group(2)) : 10;
+ }
+
+ private String extractStatus(String text) {
+ if (containsAny(text, "寰呭鏍�", "寰呭鎵�")) {
+ return "pending";
+ }
+ if (containsAny(text, "瀹℃牳涓�", "澶勭悊涓�", "澶勭悊涓殑", "鍔炵悊涓�")) {
+ return "processing";
+ }
+ if (containsAny(text, "宸查�氳繃", "閫氳繃", "瀹℃牳瀹屾垚", "瀹℃壒瀹屾垚")) {
+ return "approved";
+ }
+ if (containsAny(text, "鏈�氳繃", "椹冲洖", "宸查┏鍥�", "鎷掔粷")) {
+ return "rejected";
+ }
+ if (containsAny(text, "閲嶆柊鎻愪氦")) {
+ return "resubmitted";
+ }
+ return "all";
+ }
+
+ private Integer extractApproveType(String text) {
+ if (text.contains("鍏嚭")) {
+ return 1;
+ }
+ if (text.contains("璇峰亣")) {
+ return 2;
+ }
+ if (text.contains("鍑哄樊")) {
+ return 3;
+ }
+ if (text.contains("鎶ラ攢")) {
+ return 4;
+ }
+ if (text.contains("閲囪喘")) {
+ return 5;
+ }
+ if (text.contains("鎶ヤ环")) {
+ return 6;
+ }
+ if (text.contains("鍙戣揣")) {
+ return 7;
+ }
+ if (text.contains("鍗遍櫓浣滀笟")) {
+ return 8;
+ }
+ return null;
+ }
+
+ private String extractKeyword(String text) {
+ String cleaned = text
+ .replace("鏌ヨ", "")
+ .replace("鏌ョ湅", "")
+ .replace("鍒楀嚭", "")
+ .replace("甯垜", "")
+ .replace("瀹℃壒", "")
+ .replace("鍗曟嵁", "")
+ .replace("寰呭姙", "")
+ .replace("鍒楄〃", "")
+ .replace("鍓�10鏉�", "")
+ .replace("鏈�杩�10鏉�", "")
+ .trim();
+ return cleaned.length() >= 2 ? cleaned : null;
+ }
+
+ private String extractValue(String text, String fieldName) {
+ Pattern pattern = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗鏄�)[:锛歖?[\\s]*([^,锛屻�傦紱;\\s]+)");
+ Matcher matcher = pattern.matcher(text);
+ return matcher.find() ? matcher.group(2) : null;
+ }
+
+ private String extractDateValue(String text, String fieldName) {
+ int index = text.indexOf(fieldName);
+ if (index < 0) {
+ return null;
+ }
+ Matcher matcher = DATE_PATTERN.matcher(text.substring(index));
+ return matcher.find() ? matcher.group(1) : null;
+ }
+
+ private String extractStartDate(String text) {
+ Matcher matcher = DATE_PATTERN.matcher(text);
+ return matcher.find() ? matcher.group(1) : null;
+ }
+
+ private String extractEndDate(String text) {
+ Matcher matcher = DATE_PATTERN.matcher(text);
+ if (!matcher.find()) {
+ return null;
+ }
+ return matcher.find() ? matcher.group(1) : null;
+ }
+
+ private String extractTimeRange(String text) {
+ if (containsAny(text, "浠婂ぉ", "鏄ㄦ棩", "鏄ㄥぉ", "鏈懆", "涓婂懆", "鏈湀", "涓婃湀", "鏈勾", "浠婂勾", "鍘诲勾")) {
+ return text;
+ }
+ if (RECENT_RANGE_PATTERN.matcher(text).find()) {
+ return text;
+ }
+ if (HALF_RANGE_PATTERN.matcher(text).find()) {
+ return text;
+ }
+ if (EXPLICIT_RANGE_PATTERN.matcher(text).matches()) {
+ return text;
+ }
+ return null;
+ }
+
+ private Integer extractIntegerValue(String text, String fieldName) {
+ if (!text.contains(fieldName)) {
+ return null;
+ }
+ Matcher matcher = Pattern.compile(fieldName + "(鏀逛负|淇敼涓簗鏄�)[:锛歖?[\\s]*(\\d{1,2})").matcher(text);
+ return matcher.find() ? Integer.parseInt(matcher.group(2)) : null;
+ }
+
+ private BigDecimal extractBigDecimalValue(String text, String fieldName) {
+ int index = text.indexOf(fieldName);
+ if (index < 0) {
+ return null;
+ }
+ Matcher matcher = NUMBER_PATTERN.matcher(text.substring(index));
+ return matcher.find() ? new BigDecimal(matcher.group(1)) : null;
+ }
+
+ private String extractTail(String text, String key) {
+ Pattern pattern = Pattern.compile(key + "(鏄瘄涓�)?[:锛歖?[\\s]*(.+)");
+ Matcher matcher = pattern.matcher(text);
+ return matcher.find() ? matcher.group(2).trim() : null;
+ }
+
+ private String extractScope(String text) {
+ if (containsAny(text, "鎴戝彂璧�", "鎴戞彁浜�", "鎴戠敵璇�", "鐢宠浜烘槸鎴�")) {
+ return "applicant";
+ }
+ if (containsAny(text, "寰呮垜瀹℃壒", "寰呮垜瀹℃牳", "鎴戝鐞�", "鎴戝鎵�", "褰撳墠寰呮垜", "闇�瑕佹垜澶勭悊")) {
+ return "approver";
+ }
+ return "related";
+ }
+
+ private String firstNonBlank(String first, String second) {
+ return StringUtils.hasText(first) ? first : second;
+ }
+
+ private String missingApproveId(String type, String description) {
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("success", false);
+ result.put("type", type);
+ result.put("description", description);
+ result.put("summary", Map.of());
+ result.put("data", Map.of());
+ result.put("charts", Map.of());
+ return JSON.toJSONString(result);
+ }
+}
--
Gitblit v1.9.3