From c32165df4d6254975bf31717f8608f417c757c2d Mon Sep 17 00:00:00 2001 From: MerCry Date: Tue, 24 Feb 2026 12:45:07 +0800 Subject: [PATCH 1/2] =?UTF-8?q?spec:=20=E8=A1=A5=E5=85=85=20X-Tenant-Id=20?= =?UTF-8?q?Header=20=E5=88=B0=20openapi.deps.yaml=20[AC-MCA-04]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/ai-robot/openapi.deps.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/ai-robot/openapi.deps.yaml b/spec/ai-robot/openapi.deps.yaml index d9ec669..5d89765 100644 --- a/spec/ai-robot/openapi.deps.yaml +++ b/spec/ai-robot/openapi.deps.yaml @@ -37,6 +37,15 @@ paths: - AC-MCA-05 - AC-MCA-06 - AC-MCA-07 + parameters: + - name: X-Tenant-Id + in: header + required: true + schema: + type: string + minLength: 1 + maxLength: 64 + description: 租户ID,用于多租户场景下的租户标识 requestBody: required: true content: From d5f3063c03b76f27945c95ac1b212e0d16673fdf Mon Sep 17 00:00:00 2001 From: MerCry Date: Thu, 26 Feb 2026 01:01:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E8=B0=83=E8=AF=95=20=E7=A1=AE=E4=BF=9D=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E8=81=94=E9=80=9Aai=E4=B8=AD=E5=8F=B0[AC-INIT]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../robot/adapter/ChannelAdapterFactory.java | 3 +- .../wecom/robot/config/AiServiceConfig.java | 2 ++ .../robot/config/ChannelAdapterConfig.java | 30 +++++++++++++++++++ .../com/wecom/robot/config/ChannelConfig.java | 6 ++++ .../robot/config/RestTemplateConfig.java | 2 +- .../controller/WecomCallbackController.java | 2 ++ .../robot/service/MessageProcessService.java | 2 ++ .../service/impl/AiServiceClientImpl.java | 1 + .../impl/MessageRouterServiceImpl.java | 9 ++++-- src/main/resources/application.yml | 3 +- 10 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/wecom/robot/config/ChannelAdapterConfig.java diff --git a/src/main/java/com/wecom/robot/adapter/ChannelAdapterFactory.java b/src/main/java/com/wecom/robot/adapter/ChannelAdapterFactory.java index 1617777..2ea8f47 100644 --- a/src/main/java/com/wecom/robot/adapter/ChannelAdapterFactory.java +++ b/src/main/java/com/wecom/robot/adapter/ChannelAdapterFactory.java @@ -3,6 +3,7 @@ package com.wecom.robot.adapter; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -17,7 +18,7 @@ import java.util.stream.Collectors; @Slf4j @Component public class ChannelAdapterFactory { - + @Resource(name = "channelAdapters") private final Map adapterMap; public ChannelAdapterFactory(List adapters) { diff --git a/src/main/java/com/wecom/robot/config/AiServiceConfig.java b/src/main/java/com/wecom/robot/config/AiServiceConfig.java index e246cda..118ff96 100644 --- a/src/main/java/com/wecom/robot/config/AiServiceConfig.java +++ b/src/main/java/com/wecom/robot/config/AiServiceConfig.java @@ -12,4 +12,6 @@ public class AiServiceConfig { private String url; private int timeout = 5000; + + private String tenantId = "szmp@ash@2026"; } diff --git a/src/main/java/com/wecom/robot/config/ChannelAdapterConfig.java b/src/main/java/com/wecom/robot/config/ChannelAdapterConfig.java new file mode 100644 index 0000000..fb2b42f --- /dev/null +++ b/src/main/java/com/wecom/robot/config/ChannelAdapterConfig.java @@ -0,0 +1,30 @@ +package com.wecom.robot.config; + +import com.wecom.robot.adapter.ChannelAdapter; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Configuration +public class ChannelAdapterConfig { + + @Bean + @Primary + public Map channelAdapters( + ObjectProvider> adapterProvider) { + return adapterProvider.getIfAvailable(Collections::emptyList) + .stream() + .collect(Collectors.toMap( + ChannelAdapter::getChannelType, + Function.identity(), + (existing, replacement) -> existing // 处理重复key + )); + } +} \ No newline at end of file diff --git a/src/main/java/com/wecom/robot/config/ChannelConfig.java b/src/main/java/com/wecom/robot/config/ChannelConfig.java index 5a10f31..5dcc244 100644 --- a/src/main/java/com/wecom/robot/config/ChannelConfig.java +++ b/src/main/java/com/wecom/robot/config/ChannelConfig.java @@ -1,10 +1,16 @@ package com.wecom.robot.config; +import com.wecom.robot.adapter.ChannelAdapter; import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; @Data @Component diff --git a/src/main/java/com/wecom/robot/config/RestTemplateConfig.java b/src/main/java/com/wecom/robot/config/RestTemplateConfig.java index a49fb63..6986c13 100644 --- a/src/main/java/com/wecom/robot/config/RestTemplateConfig.java +++ b/src/main/java/com/wecom/robot/config/RestTemplateConfig.java @@ -12,7 +12,7 @@ public class RestTemplateConfig { public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(5000); - factory.setReadTimeout(5000); + factory.setReadTimeout(30000); return new RestTemplate(factory); } } diff --git a/src/main/java/com/wecom/robot/controller/WecomCallbackController.java b/src/main/java/com/wecom/robot/controller/WecomCallbackController.java index 5bb3132..ea937f7 100644 --- a/src/main/java/com/wecom/robot/controller/WecomCallbackController.java +++ b/src/main/java/com/wecom/robot/controller/WecomCallbackController.java @@ -12,6 +12,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import java.util.Map; /** @@ -31,6 +32,7 @@ public class WecomCallbackController { private final WecomConfig wecomConfig; private final MessageProcessService messageProcessService; private final MessageRouterService messageRouterService; + @Resource(name = "channelAdapters") private final Map channelAdapters; @GetMapping("/callback") diff --git a/src/main/java/com/wecom/robot/service/MessageProcessService.java b/src/main/java/com/wecom/robot/service/MessageProcessService.java index 34530d8..3e883cb 100644 --- a/src/main/java/com/wecom/robot/service/MessageProcessService.java +++ b/src/main/java/com/wecom/robot/service/MessageProcessService.java @@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.List; import java.util.Map; @@ -35,6 +36,7 @@ public class MessageProcessService { private final WecomApiService wecomApiService; private final WebSocketService webSocketService; private final MessageRouterService messageRouterService; + @Resource(name = "channelAdapters") private final Map channelAdapters; @Async diff --git a/src/main/java/com/wecom/robot/service/impl/AiServiceClientImpl.java b/src/main/java/com/wecom/robot/service/impl/AiServiceClientImpl.java index 8193d82..86a46e6 100644 --- a/src/main/java/com/wecom/robot/service/impl/AiServiceClientImpl.java +++ b/src/main/java/com/wecom/robot/service/impl/AiServiceClientImpl.java @@ -37,6 +37,7 @@ public class AiServiceClientImpl implements AiServiceClient { String url = aiServiceConfig.getUrl() + CHAT_ENDPOINT; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("X-Tenant-Id", aiServiceConfig.getTenantId()); HttpEntity entity = new HttpEntity<>(request, headers); ResponseEntity response = restTemplate.postForEntity( diff --git a/src/main/java/com/wecom/robot/service/impl/MessageRouterServiceImpl.java b/src/main/java/com/wecom/robot/service/impl/MessageRouterServiceImpl.java index bda8152..28e2de2 100644 --- a/src/main/java/com/wecom/robot/service/impl/MessageRouterServiceImpl.java +++ b/src/main/java/com/wecom/robot/service/impl/MessageRouterServiceImpl.java @@ -11,10 +11,12 @@ import com.wecom.robot.entity.Session; import com.wecom.robot.service.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,7 +34,8 @@ public class MessageRouterServiceImpl implements MessageRouterService { private final AiServiceClient aiServiceClient; private final TransferService transferService; private final WebSocketService webSocketService; - private final Map channelAdapters; + @Resource(name = "channelAdapters") + private final Map channelAdapterMap; private final StringRedisTemplate redisTemplate; @Override @@ -198,7 +201,7 @@ public class MessageRouterServiceImpl implements MessageRouterService { String transferReply = reply + "\n\n正在为您转接人工客服,请稍候..."; - ChannelAdapter adapter = channelAdapters.get(message.getChannelType()); + ChannelAdapter adapter = channelAdapterMap.get(message.getChannelType()); if (adapter != null) { OutboundMessage outbound = OutboundMessage.builder() .channelType(message.getChannelType()) @@ -222,7 +225,7 @@ public class MessageRouterServiceImpl implements MessageRouterService { } private void sendReplyToUser(Session session, InboundMessage message, String reply) { - ChannelAdapter adapter = channelAdapters.get(message.getChannelType()); + ChannelAdapter adapter = channelAdapterMap.get(message.getChannelType()); if (adapter != null) { OutboundMessage outbound = OutboundMessage.builder() .channelType(message.getChannelType()) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 303dd11..c4b50ba 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -32,12 +32,13 @@ transfer: - 人工客服 confidence-threshold: 0.6 max-fail-rounds: 3 - max-session-duration: 1800000 + max-session-duration: 180000000 max-message-rounds: 50 ai-service: url: http://localhost:8000 timeout: 5000 + tenantId: szmp@ash@2026 channel: default-channel: wechat