union-ark-web 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROJECT_OVERVIEW.md +405 -0
- package/README.md +177 -0
- package/ark-control/pom.xml +142 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SecurityResult.java +14 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SymmetricalSecurityService.java +11 -0
- package/ark-control/src/local-mock/java/com/epcc/dubbo/result/Result.java +29 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptField.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldLong.java +17 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldWithTag.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/BaseDataErrorCode.java +26 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/CheckException.java +33 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/ErrorCode.java +9 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/redis/RedisCacheService.java +131 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/Constant.java +24 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/ResultUtil.java +9 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalMockSensitiveProxy.java +40 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalRedisCacheService.java +45 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveHostConfiguration.java +27 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveProxyConfiguration.java +16 -0
- package/ark-control/src/main/java/com/union/control/ArkControlApplication.java +17 -0
- package/ark-control/src/main/java/com/union/control/dubbo/ProviderAccessLogFilter.java +45 -0
- package/ark-control/src/main/java/com/union/control/mapper/AgentExecutionMapper.java +35 -0
- package/ark-control/src/main/java/com/union/control/mapper/ConversationMapper.java +44 -0
- package/ark-control/src/main/java/com/union/control/mapper/MemoryStoreMapper.java +41 -0
- package/ark-control/src/main/java/com/union/control/mapper/ScheduledTaskMapper.java +96 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveAddressBookDemo.java +31 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveDataDemoMapper.java +24 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AESInterceptor.java +265 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AddressBookHandler.java +105 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledExecutionToken.java +55 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledTaskScheduler.java +206 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentExecutionServiceImpl.java +212 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentProxyServiceImpl.java +143 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ConversationServiceImpl.java +245 -0
- package/ark-control/src/main/java/com/union/control/service/impl/MemoryStoreServiceImpl.java +252 -0
- package/ark-control/src/main/java/com/union/control/service/impl/RunningAnalysisMockServiceImpl.java +301 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ScheduledTaskServiceImpl.java +576 -0
- package/ark-control/src/main/java/com/union/control/service/impl/SensitiveDataDemoServiceImpl.java +144 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/RedisRevealTokenStore.java +90 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealProcessor.java +319 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealServiceImpl.java +72 -0
- package/ark-control/src/main/java/com/union/control/utils/AgentSupport.java +103 -0
- package/ark-control/src/main/java/com/union/control/utils/security/SymmetricalSecurityUtils.java +160 -0
- package/ark-control/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter +1 -0
- package/ark-control/src/main/resources/application.properties +4 -0
- package/ark-control/src/main/resources/application.yml +32 -0
- package/ark-control/src/main/resources/dubbo-provider.xml +20 -0
- package/ark-control/src/main/resources/mapper/AgentExecutionMapper.xml +75 -0
- package/ark-control/src/main/resources/mapper/ConversationMapper.xml +110 -0
- package/ark-control/src/main/resources/mapper/MemoryStoreMapper.xml +74 -0
- package/ark-control/src/main/resources/mapper/ScheduledTaskMapper.xml +286 -0
- package/ark-control/src/main/resources/mapper/SensitiveDataDemoMapper.xml +55 -0
- package/ark-control/src/main/resources/schema.sql +146 -0
- package/ark-control/src/test/java/com/union/control/AgentExecutionServiceTest.java +170 -0
- package/ark-control/src/test/java/com/union/control/ArkControlStructureContractTest.java +107 -0
- package/ark-control/src/test/java/com/union/control/ConversationServiceTest.java +89 -0
- package/ark-control/src/test/java/com/union/control/MemoryStoreServiceTest.java +26 -0
- package/ark-control/src/test/java/com/union/control/PydanticAiControlContractTest.java +52 -0
- package/ark-control/src/test/java/com/union/control/TestJson.java +45 -0
- package/ark-control/src/test/java/com/union/control/dubbo/ProviderAccessLogFilterTest.java +53 -0
- package/ark-control/src/test/java/com/union/control/local/sensitive/LocalSensitiveProxyConfigurationTest.java +23 -0
- package/ark-control/src/test/java/com/union/control/mapper/interceptor/AESInterceptorCompatibilityTest.java +505 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledExecutionTokenTest.java +27 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledTaskSchedulerTest.java +51 -0
- package/ark-control/src/test/java/com/union/control/service/AgentProxyServiceTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/ScheduledTaskServiceTest.java +483 -0
- package/ark-control/src/test/java/com/union/control/service/impl/SensitiveDataDemoServiceImplTest.java +104 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/RedisRevealTokenStoreTest.java +65 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealBoundaryTest.java +99 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorCodecTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/utils/security/SymmetricalSecurityUtilsCompatibilityTest.java +87 -0
- package/ark-control-facade/pom.xml +16 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentExecutionService.java +8 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentProxyService.java +7 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentResponse.java +22 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ConversationService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/MemoryStoreService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/RunningAnalysisMockService.java +10 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ScheduledTaskService.java +40 -0
- package/ark-control-facade/src/main/java/com/union/control/service/SensitiveDataDemoService.java +13 -0
- package/ark-control-facade/src/main/java/com/union/control/service/sensitive/SensitiveRevealService.java +18 -0
- package/ark-web/README.md +80 -0
- package/ark-web/pom.xml +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/ArkAuthServiceMock.java +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/LocalKaptchaConfiguration.java +26 -0
- package/ark-web/src/main/java/com/epcc/arkweb/Application.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/InterceptorConfig.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/Realm.java +64 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/ShiroConfig.java +129 -0
- package/ark-web/src/main/java/com/epcc/arkweb/filter/LoginFormFilter.java +43 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthContextHolder.java +39 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthenticatedRequest.java +91 -0
- package/ark-web/src/main/java/com/epcc/arkweb/model/ShiroUser.java +21 -0
- package/ark-web/src/main/java/com/epcc/arkweb/utils/ResultMsg.java +19 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskCommandVO.java +30 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskQueryVO.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/CommonController.java +25 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptor.java +229 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentController.java +165 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentPermission.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/LlmController.java +209 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/ScheduledTaskController.java +160 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveCaptchaService.java +146 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealController.java +163 -0
- package/ark-web/src/main/resources/application.properties +1 -0
- package/ark-web/src/main/resources/application.yml +23 -0
- package/ark-web/src/main/resources/dubbo-consumer.xml +19 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/CasShiroConfig.java +229 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/InterceptorConfig.java +35 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/ShiroConfig.java +161 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ArkWebStructureContractTest.java +290 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ShiroTestSupport.java +32 -0
- package/ark-web/src/test/java/com/epcc/arkweb/config/LocalShiroIntegrationTest.java +121 -0
- package/ark-web/src/test/java/com/epcc/arkweb/helper/AuthenticatedRequestTest.java +131 -0
- package/ark-web/src/test/java/com/epcc/arkweb/local/LocalArkAuthServiceMockTest.java +17 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptorTest.java +134 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentControllerAuthorizationTest.java +97 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/LlmControllerTest.java +113 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealControllerTest.java +273 -0
- package/package.json +18 -0
- package/pom.xml +16 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
package com.union.control.utils;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.core.type.TypeReference;
|
|
4
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
5
|
+
|
|
6
|
+
import java.util.LinkedHashMap;
|
|
7
|
+
import java.util.Map;
|
|
8
|
+
import java.util.regex.Pattern;
|
|
9
|
+
|
|
10
|
+
public final class AgentSupport {
|
|
11
|
+
private static final Pattern ID = Pattern.compile("[A-Za-z0-9._:@-]{1,64}");
|
|
12
|
+
|
|
13
|
+
private AgentSupport() {}
|
|
14
|
+
|
|
15
|
+
public static Map<String, Object> request(ObjectMapper json, String input) {
|
|
16
|
+
if (input == null) throw new IllegalArgumentException("请求参数非法");
|
|
17
|
+
try {
|
|
18
|
+
Map<String, Object> value = json.readValue(
|
|
19
|
+
input, new TypeReference<Map<String, Object>>() {});
|
|
20
|
+
if (value == null) throw new IllegalArgumentException("请求参数非法");
|
|
21
|
+
return value;
|
|
22
|
+
} catch (IllegalArgumentException error) {
|
|
23
|
+
throw error;
|
|
24
|
+
} catch (Exception error) {
|
|
25
|
+
throw new IllegalArgumentException("请求参数不是合法 JSON", error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public static String userId(Map<String, Object> request) {
|
|
30
|
+
return identity(request, "userId");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public static String identity(Map<String, Object> request, String field) {
|
|
34
|
+
String value = text(request, field, 64, true);
|
|
35
|
+
if (value == null || value.trim().isEmpty())
|
|
36
|
+
throw new IllegalArgumentException(field + " 非法");
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public static void requireId(String value) {
|
|
41
|
+
if (value == null || !ID.matcher(value).matches())
|
|
42
|
+
throw new IllegalArgumentException("conversationId 非法");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static void requireExecutionToken(String value) {
|
|
46
|
+
if (value == null || !ID.matcher(value).matches())
|
|
47
|
+
throw new IllegalArgumentException("runId 非法");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public static int integer(Map<String, Object> values, String key, int min, int max) {
|
|
51
|
+
Object raw = values.get(key);
|
|
52
|
+
if (!(raw instanceof Number)) throw new IllegalArgumentException(key + " 非法");
|
|
53
|
+
int value = ((Number) raw).intValue();
|
|
54
|
+
requireRange(value, min, max, key);
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static long number(Object value) {
|
|
59
|
+
return value instanceof Number
|
|
60
|
+
? ((Number) value).longValue()
|
|
61
|
+
: Long.parseLong(String.valueOf(value));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static String optionalText(Map<String, Object> values, String key, int max) {
|
|
65
|
+
return text(values, key, max, false);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public static String text(Map<?, ?> values, String key, int max, boolean required) {
|
|
69
|
+
Object raw = values.get(key);
|
|
70
|
+
if (raw != null && !(raw instanceof String))
|
|
71
|
+
throw new IllegalArgumentException(key + " 非法");
|
|
72
|
+
String value = raw == null ? null : ((String) raw).trim();
|
|
73
|
+
if (value != null && value.isEmpty()) value = null;
|
|
74
|
+
if ((required && value == null) || (value != null && value.length() > max))
|
|
75
|
+
throw new IllegalArgumentException(key + " 非法");
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static void requireRange(int value, int min, int max, String name) {
|
|
80
|
+
if (value < min || value > max)
|
|
81
|
+
throw new IllegalArgumentException(name + " 超出范围");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public static String likePrefix(String prefix) {
|
|
85
|
+
return prefix.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_") + "%";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public static boolean same(String left, String right) {
|
|
89
|
+
return left == null ? right == null : left.equals(right);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public static Map<String, Object> success() {
|
|
93
|
+
Map<String, Object> response = new LinkedHashMap<>();
|
|
94
|
+
response.put("success", true);
|
|
95
|
+
return response;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public static Map<String, Object> ok(Object data) {
|
|
99
|
+
Map<String, Object> response = success();
|
|
100
|
+
response.put("data", data);
|
|
101
|
+
return response;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/ark-control/src/main/java/com/union/control/utils/security/SymmetricalSecurityUtils.java
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
package com.union.control.utils.security;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SecurityResult;
|
|
4
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
5
|
+
import com.epcc.dubbo.result.Result;
|
|
6
|
+
import com.nucc.channel.ark.common.exception.BaseDataErrorCode;
|
|
7
|
+
import com.nucc.channel.ark.common.exception.CheckException;
|
|
8
|
+
import org.apache.commons.codec.binary.Base64;
|
|
9
|
+
import org.slf4j.Logger;
|
|
10
|
+
import org.slf4j.LoggerFactory;
|
|
11
|
+
import org.springframework.stereotype.Component;
|
|
12
|
+
|
|
13
|
+
import javax.annotation.Resource;
|
|
14
|
+
import java.nio.charset.StandardCharsets;
|
|
15
|
+
import java.util.ArrayList;
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.regex.Matcher;
|
|
18
|
+
import java.util.regex.Pattern;
|
|
19
|
+
|
|
20
|
+
import static com.nucc.channel.ark.common.util.Constant.ENCRYPT_END;
|
|
21
|
+
import static com.nucc.channel.ark.common.util.Constant.ENCRYPT_START;
|
|
22
|
+
import static com.nucc.channel.ark.common.util.Constant.REGEX_DECRYPT_TAG;
|
|
23
|
+
import static com.nucc.channel.ark.common.util.Constant.REGEX_EMAIL;
|
|
24
|
+
import static com.nucc.channel.ark.common.util.Constant.REGEX_MOBILE;
|
|
25
|
+
import static com.nucc.channel.ark.common.util.Constant.REGEX_TELEPHONE;
|
|
26
|
+
|
|
27
|
+
/** Production-equivalent crypto utility; cryptography remains behind sensitiveProxy. */
|
|
28
|
+
@Component
|
|
29
|
+
public class SymmetricalSecurityUtils {
|
|
30
|
+
private static final Logger LOG = LoggerFactory.getLogger(SymmetricalSecurityUtils.class);
|
|
31
|
+
private static final Pattern MOBILE = Pattern.compile(REGEX_MOBILE);
|
|
32
|
+
private static final Pattern EMAIL = Pattern.compile(REGEX_EMAIL);
|
|
33
|
+
private static final Pattern TELEPHONE = Pattern.compile(REGEX_TELEPHONE);
|
|
34
|
+
private static final Pattern DECRYPT_TAG = Pattern.compile(REGEX_DECRYPT_TAG);
|
|
35
|
+
|
|
36
|
+
@Resource(name = "sensitiveProxy")
|
|
37
|
+
private SymmetricalSecurityService symmetricalSecurityService;
|
|
38
|
+
|
|
39
|
+
public SymmetricalSecurityUtils() {}
|
|
40
|
+
|
|
41
|
+
public SymmetricalSecurityUtils(SymmetricalSecurityService symmetricalSecurityService) {
|
|
42
|
+
this.symmetricalSecurityService = symmetricalSecurityService;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public String encryptLongString(String plaintext, int chunkSize) throws CheckException {
|
|
46
|
+
if (chunkSize == 0) return encryptByFixKey(plaintext);
|
|
47
|
+
List<String> chunks = new ArrayList<>();
|
|
48
|
+
for (int i = 0; i < plaintext.length(); i += chunkSize) {
|
|
49
|
+
chunks.add(encryptByFixKey(plaintext.substring(i, Math.min(plaintext.length(), i + chunkSize))));
|
|
50
|
+
}
|
|
51
|
+
return join(chunks, "|");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public String encryptWithTag(String plaintext) throws CheckException {
|
|
55
|
+
if (isBlank(plaintext)) return "";
|
|
56
|
+
String value = replaceEncrypted(MOBILE, plaintext);
|
|
57
|
+
value = replaceEncrypted(EMAIL, value);
|
|
58
|
+
return replaceEncrypted(TELEPHONE, value);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public String decryptLongString(String ciphertext) throws CheckException {
|
|
62
|
+
String[] chunks = ciphertext.split("\\|");
|
|
63
|
+
StringBuilder result = new StringBuilder();
|
|
64
|
+
for (String chunk : chunks) result.append(decryptWithCheckNoLog(chunk));
|
|
65
|
+
return result.toString();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public String decryptWithTag(String ciphertext) throws CheckException {
|
|
69
|
+
if (isBlank(ciphertext)) return "";
|
|
70
|
+
StringBuilder value = new StringBuilder(ciphertext);
|
|
71
|
+
Matcher matcher = DECRYPT_TAG.matcher(value);
|
|
72
|
+
while (matcher.find()) {
|
|
73
|
+
value.replace(matcher.start(), matcher.end(), decryptWithCheckNoLog(matcher.group(1)));
|
|
74
|
+
matcher.reset(value);
|
|
75
|
+
}
|
|
76
|
+
return value.toString();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public String encryptWithCheck(String plaintext) throws CheckException {
|
|
80
|
+
return isBlank(plaintext) ? plaintext : encryptByFixKey(plaintext);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public String decryptWithCheck(String ciphertext) {
|
|
84
|
+
if (isBlank(ciphertext)) return ciphertext;
|
|
85
|
+
try {
|
|
86
|
+
return decryptByFixKey(ciphertext);
|
|
87
|
+
} catch (CheckException error) {
|
|
88
|
+
LOG.error("decryptWithCheck failed error_type={}", error.getClass().getSimpleName());
|
|
89
|
+
return ciphertext;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public String decryptWithCheckNoLog(String ciphertext) throws CheckException {
|
|
94
|
+
return isBlank(ciphertext) ? ciphertext : decryptByFixKey(ciphertext);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private String replaceEncrypted(Pattern pattern, String plaintext) throws CheckException {
|
|
98
|
+
StringBuilder value = new StringBuilder(plaintext);
|
|
99
|
+
Matcher matcher = pattern.matcher(value);
|
|
100
|
+
while (matcher.find()) {
|
|
101
|
+
value.replace(matcher.start(), matcher.end(),
|
|
102
|
+
ENCRYPT_START + encryptByFixKey(matcher.group()) + ENCRYPT_END);
|
|
103
|
+
matcher.reset(value);
|
|
104
|
+
}
|
|
105
|
+
return value.toString();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private String encryptByFixKey(String plaintext) throws CheckException {
|
|
109
|
+
long started = System.currentTimeMillis();
|
|
110
|
+
Result<SecurityResult> result = symmetricalSecurityService.encryptByFixedKey(
|
|
111
|
+
SymmetricalSecurityService.Algorithm.AES256,
|
|
112
|
+
plaintext.getBytes(StandardCharsets.UTF_8));
|
|
113
|
+
if (!result.isSuccess()) throw remoteFailure(result);
|
|
114
|
+
debug("encryptByFixKey", started);
|
|
115
|
+
return Base64.encodeBase64String(result.getResult().getContent());
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private String decryptByFixKey(String ciphertext) throws CheckException {
|
|
119
|
+
long started = System.currentTimeMillis();
|
|
120
|
+
final byte[] decoded;
|
|
121
|
+
try {
|
|
122
|
+
decoded = Base64.decodeBase64(ciphertext);
|
|
123
|
+
} catch (IllegalArgumentException error) {
|
|
124
|
+
throw new CheckException(BaseDataErrorCode.SYSTEM_INNER_ERROR, "Invalid ciphertext");
|
|
125
|
+
}
|
|
126
|
+
Result<SecurityResult> result = symmetricalSecurityService.decryptByFixedKey(
|
|
127
|
+
SymmetricalSecurityService.Algorithm.AES256, decoded);
|
|
128
|
+
if (!result.isSuccess()) throw remoteFailure(result);
|
|
129
|
+
String plaintext = new String(result.getResult().getContent(), StandardCharsets.UTF_8);
|
|
130
|
+
debug("decryptByFixKey", started);
|
|
131
|
+
return plaintext;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private void debug(String operation, long started) {
|
|
135
|
+
if (LOG.isDebugEnabled()) LOG.debug("SymmetricalSecurityUtils.{} elapsedMs={}",
|
|
136
|
+
operation, System.currentTimeMillis() - started);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private static CheckException remoteFailure(Result<SecurityResult> result) {
|
|
140
|
+
return new CheckException(BaseDataErrorCode.SYSTEM_INNER_ERROR,
|
|
141
|
+
result.getErrorCode() + "|" + result.getErrorMsg());
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private static boolean isBlank(String value) {
|
|
145
|
+
if (value == null || value.isEmpty()) return true;
|
|
146
|
+
for (int i = 0; i < value.length(); i++) {
|
|
147
|
+
if (!Character.isWhitespace(value.charAt(i))) return false;
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private static String join(List<String> values, String delimiter) {
|
|
153
|
+
StringBuilder result = new StringBuilder();
|
|
154
|
+
for (String value : values) {
|
|
155
|
+
if (result.length() > 0) result.append(delimiter);
|
|
156
|
+
result.append(value);
|
|
157
|
+
}
|
|
158
|
+
return result.toString();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
providerAccessLog=com.union.control.dubbo.ProviderAccessLogFilter
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
sensitive.reveal.enabled=${SENSITIVE_REVEAL_ENABLED:true}
|
|
2
|
+
sensitive.reveal.strict_mode=${SENSITIVE_REVEAL_STRICT_MODE:true}
|
|
3
|
+
sensitive.reveal.ttl-seconds=${SENSITIVE_REVEAL_TTL_SECONDS:300}
|
|
4
|
+
sensitive.address-book.plaintext-roles=${SENSITIVE_ADDRESS_BOOK_PLAINTEXT_ROLES:001,002,003}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
py-app-base-url: ${PY_APP_BASE_URL:http://127.0.0.1:8083}
|
|
3
|
+
scheduled-enabled: ${SCHEDULED_TASK_ENABLED:true}
|
|
4
|
+
scheduled-worker-threads: ${SCHEDULED_TASK_WORKER_THREADS:2}
|
|
5
|
+
scheduled-max-run-seconds: ${SCHEDULED_TASK_MAX_RUN_SECONDS:930}
|
|
6
|
+
scheduled-token-ttl-seconds: ${SCHEDULED_TASK_TOKEN_TTL_SECONDS:960}
|
|
7
|
+
|
|
8
|
+
dubbo:
|
|
9
|
+
application:
|
|
10
|
+
name: ark-control
|
|
11
|
+
registry:
|
|
12
|
+
address: ${DUBBO_REGISTRY_ADDRESS:zookeeper://127.0.0.1:2181}
|
|
13
|
+
protocol:
|
|
14
|
+
port: ${DUBBO_PROTOCOL_PORT:20880}
|
|
15
|
+
|
|
16
|
+
spring:
|
|
17
|
+
main:
|
|
18
|
+
web-environment: false
|
|
19
|
+
datasource:
|
|
20
|
+
url: ${MYSQL_URL:jdbc:mysql://127.0.0.1:3306/union_control?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC}
|
|
21
|
+
username: ${MYSQL_USER:root}
|
|
22
|
+
password: ${MYSQL_PASSWORD:mmls@HW902}
|
|
23
|
+
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
24
|
+
initialize: true
|
|
25
|
+
redis:
|
|
26
|
+
host: ${REDIS_HOST:127.0.0.1}
|
|
27
|
+
port: ${REDIS_PORT:6379}
|
|
28
|
+
password: ${REDIS_PASSWORD:mmls@HW902}
|
|
29
|
+
timeout: ${REDIS_TIMEOUT_MS:2000}
|
|
30
|
+
|
|
31
|
+
mybatis:
|
|
32
|
+
mapper-locations: classpath*:mapper/*.xml
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
|
5
|
+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
|
6
|
+
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
|
7
|
+
<dubbo:application name="${dubbo.application.name}"/>
|
|
8
|
+
<dubbo:registry address="${dubbo.registry.address}"/>
|
|
9
|
+
<dubbo:protocol name="dubbo" port="${dubbo.protocol.port}" transporter="netty4"/>
|
|
10
|
+
<dubbo:provider filter="providerAccessLog"/>
|
|
11
|
+
|
|
12
|
+
<dubbo:service interface="com.union.control.service.AgentExecutionService" ref="agentExecutionService"/>
|
|
13
|
+
<dubbo:service interface="com.union.control.service.AgentProxyService" ref="agentProxyService"/>
|
|
14
|
+
<dubbo:service interface="com.union.control.service.ConversationService" ref="conversationService"/>
|
|
15
|
+
<dubbo:service interface="com.union.control.service.MemoryStoreService" ref="memoryStoreService"/>
|
|
16
|
+
<dubbo:service interface="com.union.control.service.RunningAnalysisMockService" ref="runningAnalysisMockService"/>
|
|
17
|
+
<dubbo:service interface="com.union.control.service.ScheduledTaskService" ref="scheduledTaskService"/>
|
|
18
|
+
<dubbo:service interface="com.union.control.service.SensitiveDataDemoService" ref="sensitiveDataDemoService"/>
|
|
19
|
+
<dubbo:service interface="com.union.control.service.sensitive.SensitiveRevealService" ref="sensitiveRevealService"/>
|
|
20
|
+
</beans>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
2
|
+
<!DOCTYPE mapper
|
|
3
|
+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
4
|
+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
5
|
+
<mapper namespace="com.union.control.mapper.AgentExecutionMapper">
|
|
6
|
+
|
|
7
|
+
<update id="softDeleteExecutions">
|
|
8
|
+
UPDATE ai_agent_execution
|
|
9
|
+
SET delete_flag=0,updated_at=CURRENT_TIMESTAMP
|
|
10
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
11
|
+
</update>
|
|
12
|
+
|
|
13
|
+
<insert id="insertRootExecution">
|
|
14
|
+
INSERT INTO ai_agent_execution
|
|
15
|
+
(run_id,conversation_id,user_id,parent_execution_id,agent_name,status,delete_flag)
|
|
16
|
+
VALUES (#{runId},#{conversationId},#{userId},NULL,NULL,'running',1)
|
|
17
|
+
</insert>
|
|
18
|
+
|
|
19
|
+
<insert id="insertCompletedRootExecution" parameterType="map"
|
|
20
|
+
useGeneratedKeys="true" keyProperty="id">
|
|
21
|
+
INSERT INTO ai_agent_execution
|
|
22
|
+
(run_id,conversation_id,user_id,parent_execution_id,agent_name,status,
|
|
23
|
+
finished_at,delete_flag,created_at,updated_at)
|
|
24
|
+
VALUES (#{runId},#{conversationId},#{userId},NULL,#{agentName},'completed',
|
|
25
|
+
CURRENT_TIMESTAMP,1,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)
|
|
26
|
+
</insert>
|
|
27
|
+
|
|
28
|
+
<update id="updateRootAgent">
|
|
29
|
+
UPDATE ai_agent_execution
|
|
30
|
+
SET agent_name=#{agentName},updated_at=CURRENT_TIMESTAMP
|
|
31
|
+
WHERE id=#{id} AND delete_flag=1
|
|
32
|
+
</update>
|
|
33
|
+
|
|
34
|
+
<insert id="insertChildExecution">
|
|
35
|
+
INSERT INTO ai_agent_execution
|
|
36
|
+
(run_id,conversation_id,user_id,parent_execution_id,agent_name,
|
|
37
|
+
delegation_tool_call_id,task,status,delete_flag)
|
|
38
|
+
VALUES (#{runId},#{conversationId},#{userId},#{parentExecutionId},#{agentName},
|
|
39
|
+
#{delegationCallId},#{task},'running',1)
|
|
40
|
+
</insert>
|
|
41
|
+
|
|
42
|
+
<select id="findExecutions" resultType="map">
|
|
43
|
+
SELECT e.id,e.run_id AS runId,e.conversation_id AS conversationId,
|
|
44
|
+
e.parent_execution_id AS parentExecutionId,p.run_id AS parentRunId,
|
|
45
|
+
e.agent_name AS agentName,e.delegation_tool_call_id AS delegationToolCallId,
|
|
46
|
+
e.task,e.status,e.error_code AS errorCode,
|
|
47
|
+
DATE_FORMAT(e.finished_at,'%Y-%m-%dT%H:%i:%s') AS finishedAt,
|
|
48
|
+
DATE_FORMAT(e.created_at,'%Y-%m-%dT%H:%i:%s') AS createdAt
|
|
49
|
+
FROM ai_agent_execution e
|
|
50
|
+
LEFT JOIN ai_agent_execution p ON p.id=e.parent_execution_id
|
|
51
|
+
WHERE e.user_id=#{userId} AND e.conversation_id=#{conversationId} AND e.delete_flag=1
|
|
52
|
+
ORDER BY e.created_at,e.id
|
|
53
|
+
</select>
|
|
54
|
+
|
|
55
|
+
<select id="findExecution" resultType="map">
|
|
56
|
+
SELECT e.id,e.run_id AS runId,e.conversation_id AS conversationId,
|
|
57
|
+
e.parent_execution_id AS parentExecutionId,p.run_id AS parentRunId,
|
|
58
|
+
e.agent_name AS agentName,e.delegation_tool_call_id AS delegationToolCallId,
|
|
59
|
+
e.task,e.status,e.error_code AS errorCode,
|
|
60
|
+
DATE_FORMAT(e.finished_at,'%Y-%m-%dT%H:%i:%s') AS finishedAt,
|
|
61
|
+
DATE_FORMAT(e.created_at,'%Y-%m-%dT%H:%i:%s') AS createdAt
|
|
62
|
+
FROM ai_agent_execution e
|
|
63
|
+
LEFT JOIN ai_agent_execution p ON p.id=e.parent_execution_id
|
|
64
|
+
WHERE e.user_id=#{userId} AND e.conversation_id=#{conversationId}
|
|
65
|
+
AND e.run_id=#{runId} AND e.delete_flag=1
|
|
66
|
+
<if test="lock">FOR UPDATE</if>
|
|
67
|
+
</select>
|
|
68
|
+
|
|
69
|
+
<update id="finishExecution">
|
|
70
|
+
UPDATE ai_agent_execution
|
|
71
|
+
SET status=#{status},error_code=#{errorCode},
|
|
72
|
+
finished_at=CURRENT_TIMESTAMP,updated_at=CURRENT_TIMESTAMP
|
|
73
|
+
WHERE id=#{id} AND delete_flag=1
|
|
74
|
+
</update>
|
|
75
|
+
</mapper>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
2
|
+
<!DOCTYPE mapper
|
|
3
|
+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
4
|
+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
5
|
+
<mapper namespace="com.union.control.mapper.ConversationMapper">
|
|
6
|
+
|
|
7
|
+
<select id="findConversations" resultType="map">
|
|
8
|
+
SELECT c.conversation_id AS conversationId,c.title,c.status,
|
|
9
|
+
DATE_FORMAT(c.created_at,'%Y-%m-%dT%H:%i:%s') AS createdAt,
|
|
10
|
+
DATE_FORMAT(c.updated_at,'%Y-%m-%dT%H:%i:%s') AS updatedAt,
|
|
11
|
+
(SELECT e.status FROM ai_agent_execution e
|
|
12
|
+
WHERE e.conversation_id=c.conversation_id AND e.user_id=c.user_id
|
|
13
|
+
AND e.parent_execution_id IS NULL AND e.delete_flag=1
|
|
14
|
+
ORDER BY e.created_at DESC,e.id DESC LIMIT 1) AS executionStatus
|
|
15
|
+
FROM ai_conversation c
|
|
16
|
+
WHERE c.user_id=#{userId} AND c.delete_flag=1
|
|
17
|
+
AND c.status='active'
|
|
18
|
+
ORDER BY c.created_at DESC,c.id DESC
|
|
19
|
+
LIMIT #{limit}
|
|
20
|
+
</select>
|
|
21
|
+
|
|
22
|
+
<select id="findConversation" resultType="map">
|
|
23
|
+
SELECT c.conversation_id AS conversationId,c.title,c.status,
|
|
24
|
+
DATE_FORMAT(c.created_at,'%Y-%m-%dT%H:%i:%s') AS createdAt,
|
|
25
|
+
DATE_FORMAT(c.updated_at,'%Y-%m-%dT%H:%i:%s') AS updatedAt,
|
|
26
|
+
(SELECT e.status FROM ai_agent_execution e
|
|
27
|
+
WHERE e.conversation_id=c.conversation_id AND e.user_id=c.user_id
|
|
28
|
+
AND e.parent_execution_id IS NULL AND e.delete_flag=1
|
|
29
|
+
ORDER BY e.created_at DESC,e.id DESC LIMIT 1) AS executionStatus
|
|
30
|
+
FROM ai_conversation c
|
|
31
|
+
WHERE c.conversation_id=#{conversationId}
|
|
32
|
+
AND c.user_id=#{userId} AND c.delete_flag=1
|
|
33
|
+
</select>
|
|
34
|
+
|
|
35
|
+
<update id="updateConversationTitle">
|
|
36
|
+
UPDATE ai_conversation
|
|
37
|
+
SET title=#{title},updated_at=CURRENT_TIMESTAMP
|
|
38
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
39
|
+
</update>
|
|
40
|
+
|
|
41
|
+
<update id="softDeleteMessages">
|
|
42
|
+
UPDATE ai_conversation_message
|
|
43
|
+
SET delete_flag=0,updated_at=CURRENT_TIMESTAMP
|
|
44
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
45
|
+
</update>
|
|
46
|
+
|
|
47
|
+
<update id="softDeleteConversation">
|
|
48
|
+
UPDATE ai_conversation
|
|
49
|
+
SET delete_flag=0,updated_at=CURRENT_TIMESTAMP
|
|
50
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
51
|
+
</update>
|
|
52
|
+
|
|
53
|
+
<insert id="insertConversation">
|
|
54
|
+
INSERT INTO ai_conversation
|
|
55
|
+
(conversation_id,user_id,title,delete_flag)
|
|
56
|
+
VALUES (#{conversationId},#{userId},#{title},1)
|
|
57
|
+
</insert>
|
|
58
|
+
|
|
59
|
+
<select id="currentMessageSequence" resultType="long">
|
|
60
|
+
SELECT COALESCE(MAX(sequence_no),0)
|
|
61
|
+
FROM ai_conversation_message
|
|
62
|
+
WHERE conversation_id=#{conversationId}
|
|
63
|
+
</select>
|
|
64
|
+
|
|
65
|
+
<insert id="insertMessage">
|
|
66
|
+
INSERT INTO ai_conversation_message
|
|
67
|
+
(conversation_id,user_id,message_id,agent_execution_id,role,sequence_no,payload,delete_flag)
|
|
68
|
+
VALUES (#{conversationId},#{userId},#{messageId},#{executionId},#{role},#{sequence},#{payload},1)
|
|
69
|
+
</insert>
|
|
70
|
+
|
|
71
|
+
<update id="touchConversation">
|
|
72
|
+
UPDATE ai_conversation
|
|
73
|
+
SET updated_at=CURRENT_TIMESTAMP
|
|
74
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
75
|
+
</update>
|
|
76
|
+
|
|
77
|
+
<select id="findRootMessages" resultType="map">
|
|
78
|
+
SELECT m.message_id AS messageId,m.role,m.payload
|
|
79
|
+
FROM ai_conversation_message m
|
|
80
|
+
JOIN ai_agent_execution e ON e.id=m.agent_execution_id
|
|
81
|
+
WHERE m.conversation_id=#{conversationId} AND m.user_id=#{userId} AND m.delete_flag=1
|
|
82
|
+
AND e.delete_flag=1 AND e.parent_execution_id IS NULL
|
|
83
|
+
ORDER BY m.sequence_no
|
|
84
|
+
</select>
|
|
85
|
+
|
|
86
|
+
<select id="findBrowserMessages" resultType="map">
|
|
87
|
+
SELECT m.message_id AS messageId,m.role,m.payload,e.run_id AS runId,
|
|
88
|
+
e.parent_execution_id AS parentExecutionId
|
|
89
|
+
FROM ai_conversation_message m
|
|
90
|
+
JOIN ai_agent_execution e ON e.id=m.agent_execution_id
|
|
91
|
+
WHERE m.conversation_id=#{conversationId} AND m.user_id=#{userId} AND m.delete_flag=1
|
|
92
|
+
AND e.delete_flag=1
|
|
93
|
+
ORDER BY m.sequence_no
|
|
94
|
+
</select>
|
|
95
|
+
|
|
96
|
+
<select id="requireOwnedActive" resultType="long">
|
|
97
|
+
SELECT id
|
|
98
|
+
FROM ai_conversation
|
|
99
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId}
|
|
100
|
+
AND status='active' AND delete_flag=1
|
|
101
|
+
</select>
|
|
102
|
+
|
|
103
|
+
<select id="requireOwned" resultType="long">
|
|
104
|
+
SELECT id
|
|
105
|
+
FROM ai_conversation
|
|
106
|
+
WHERE conversation_id=#{conversationId} AND user_id=#{userId} AND delete_flag=1
|
|
107
|
+
<if test="lock">FOR UPDATE</if>
|
|
108
|
+
</select>
|
|
109
|
+
</mapper>
|
|
110
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
2
|
+
<!DOCTYPE mapper
|
|
3
|
+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
4
|
+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
5
|
+
<mapper namespace="com.union.control.mapper.MemoryStoreMapper">
|
|
6
|
+
|
|
7
|
+
<select id="readMemory" resultType="map">
|
|
8
|
+
SELECT content,version,last_operation_id AS operationId
|
|
9
|
+
FROM ai_memory_file
|
|
10
|
+
WHERE user_id=#{userId} AND path=#{path} AND delete_flag=1
|
|
11
|
+
</select>
|
|
12
|
+
|
|
13
|
+
<select id="listMemoryPaths" resultType="string">
|
|
14
|
+
SELECT path
|
|
15
|
+
FROM ai_memory_file
|
|
16
|
+
WHERE user_id=#{userId} AND delete_flag=1 AND path LIKE #{prefix}
|
|
17
|
+
ORDER BY path
|
|
18
|
+
LIMIT #{limit}
|
|
19
|
+
</select>
|
|
20
|
+
|
|
21
|
+
<select id="findMemoryOperation" resultType="map">
|
|
22
|
+
SELECT fingerprint,result_version AS resultVersion,existed
|
|
23
|
+
FROM ai_memory_operation
|
|
24
|
+
WHERE user_id=#{userId} AND operation_id=#{operationId}
|
|
25
|
+
<if test="lock">FOR UPDATE</if>
|
|
26
|
+
</select>
|
|
27
|
+
|
|
28
|
+
<select id="currentMemoryVersion" resultType="long">
|
|
29
|
+
SELECT COALESCE(MAX(version),0)
|
|
30
|
+
FROM ai_memory_file
|
|
31
|
+
WHERE user_id=#{userId} AND path=#{path}
|
|
32
|
+
</select>
|
|
33
|
+
|
|
34
|
+
<update id="updateMemoryFile">
|
|
35
|
+
UPDATE ai_memory_file
|
|
36
|
+
SET content=#{content},version=#{version},last_operation_id=#{operationId},
|
|
37
|
+
updated_at=CURRENT_TIMESTAMP
|
|
38
|
+
WHERE id=#{id} AND delete_flag=1
|
|
39
|
+
</update>
|
|
40
|
+
|
|
41
|
+
<insert id="insertMemoryFile">
|
|
42
|
+
INSERT INTO ai_memory_file
|
|
43
|
+
(user_id,path,content,version,last_operation_id,delete_flag)
|
|
44
|
+
VALUES (#{userId},#{path},#{content},#{version},#{operationId},1)
|
|
45
|
+
</insert>
|
|
46
|
+
|
|
47
|
+
<update id="softDeleteMemoryFile">
|
|
48
|
+
UPDATE ai_memory_file
|
|
49
|
+
SET delete_flag=0,updated_at=CURRENT_TIMESTAMP
|
|
50
|
+
WHERE id=#{id} AND delete_flag=1
|
|
51
|
+
</update>
|
|
52
|
+
|
|
53
|
+
<select id="searchMemory" resultType="map">
|
|
54
|
+
SELECT path,content
|
|
55
|
+
FROM ai_memory_file
|
|
56
|
+
WHERE user_id=#{userId} AND delete_flag=1 AND path LIKE #{prefix}
|
|
57
|
+
ORDER BY path
|
|
58
|
+
LIMIT #{limit}
|
|
59
|
+
</select>
|
|
60
|
+
|
|
61
|
+
<select id="findMemoryRow" resultType="map">
|
|
62
|
+
SELECT id,version
|
|
63
|
+
FROM ai_memory_file
|
|
64
|
+
WHERE user_id=#{userId} AND path=#{path} AND delete_flag=1
|
|
65
|
+
FOR UPDATE
|
|
66
|
+
</select>
|
|
67
|
+
|
|
68
|
+
<insert id="insertMemoryOperation">
|
|
69
|
+
INSERT INTO ai_memory_operation
|
|
70
|
+
(user_id,operation_id,fingerprint,result_version,existed,delete_flag)
|
|
71
|
+
VALUES (#{userId},#{operationId},#{fingerprint},#{version},#{existed},1)
|
|
72
|
+
</insert>
|
|
73
|
+
</mapper>
|
|
74
|
+
|