diff --git a/admin-web/src/views/Conversation.vue b/admin-web/src/views/Conversation.vue index c371875..a5ae4c8 100644 --- a/admin-web/src/views/Conversation.vue +++ b/admin-web/src/views/Conversation.vue @@ -30,7 +30,7 @@ @@ -76,7 +76,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -326,6 +326,12 @@ watch([searchQuery, typeFilter], () => { currentPage.value = 1 }) +watch(() => dialogForm.conversationType, (val) => { + if (val === 1) { + dialogForm.conversationScene = undefined + } +}) + function resetDialogForm() { dialogForm.conversationType = 2 dialogForm.channelType = 'wecom' @@ -401,7 +407,8 @@ function formatConversationType(type: number | undefined) { return type ?? '-' } -function formatConversationScene(scene: number | undefined) { +function formatConversationScene(scene: number | undefined, type?: number) { + if (type === 1) return '-' if (scene === 1) return '内部群' if (scene === 2) return '外部群' return scene ?? '-' diff --git a/backend/mci-channel-wecom/src/main/java/com/sino/mci/channel/wecom/WeComBotSender.java b/backend/mci-channel-wecom/src/main/java/com/sino/mci/channel/wecom/WeComBotSender.java index 5152459..3094713 100644 --- a/backend/mci-channel-wecom/src/main/java/com/sino/mci/channel/wecom/WeComBotSender.java +++ b/backend/mci-channel-wecom/src/main/java/com/sino/mci/channel/wecom/WeComBotSender.java @@ -91,7 +91,7 @@ public class WeComBotSender { String customUrl = getString(extra, "webhook_url"); if (customUrl != null && !customUrl.isBlank()) { if (customUrl.contains("%s")) { - return customUrl.replace("%s", key); + return customUrl.replaceFirst("%s", key); } return customUrl; } diff --git a/backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java b/backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java index 9fc0193..3e171b3 100644 --- a/backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java +++ b/backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java @@ -742,10 +742,6 @@ public class SendService { return CollectionUtils.isEmpty(accounts) ? null : accounts.get(0); } - private Long selectDefaultAccount(String tenantCode, ChannelType channelType) { - return selectDefaultAccount(tenantCode, channelType, null); - } - private Long selectDefaultAccount(String tenantCode, ChannelType channelType, Set accountTypes) { List accounts = accountMapper.selectList( new LambdaQueryWrapper() diff --git a/backend/mci-server/src/test/java/com/sino/mci/send/service/SendEndToEndTest.java b/backend/mci-server/src/test/java/com/sino/mci/send/service/SendEndToEndTest.java index a299875..5dd3138 100644 --- a/backend/mci-server/src/test/java/com/sino/mci/send/service/SendEndToEndTest.java +++ b/backend/mci-server/src/test/java/com/sino/mci/send/service/SendEndToEndTest.java @@ -52,10 +52,11 @@ class SendEndToEndTest { .andReturn().getResponse().getContentAsString(); Long subjectId = ((Number) com.jayway.jsonpath.JsonPath.read(subjectResponse, "$.data.id")).longValue(); - // 2. 创建渠道账号 + // 2. 创建外部群发送账号(pywechat 个人号) + String accountCode = "wxid-e2e-" + UUID.randomUUID().toString().substring(0, 8); String accountPayload = String.format( - "{\"accountType\":1,\"channelType\":\"wecom\",\"subjectId\":%d,\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}", - subjectId); + "{\"accountType\":3,\"channelType\":\"wechat_personal\",\"subjectId\":%d,\"accountId\":\"%s\",\"accountName\":\"张三\"}", + subjectId, accountCode); String accountResponse = mockMvc.perform(post("/msg-platform/api/v1/channel-account") .contextPath("/msg-platform") .header("Authorization", authToken) @@ -67,10 +68,20 @@ class SendEndToEndTest { .andReturn().getResponse().getContentAsString(); Long accountId = ((Number) com.jayway.jsonpath.JsonPath.read(accountResponse, "$.data.id")).longValue(); - // 3. 创建会话 + // 个人号需要心跳才能被路由视为可用 + mockMvc.perform(post("/msg-platform/api/v1/channel-account/heartbeat") + .contextPath("/msg-platform") + .header("Authorization", authToken) + .header("X-Tenant-Code", tenantCode) + .contentType(MediaType.APPLICATION_JSON) + .content(String.format("{\"accountId\":\"%s\",\"riskLevel\":1}", accountCode))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(0)); + + // 3. 创建外部群会话 String channelConversationId = "room-" + UUID.randomUUID().toString().substring(0, 8); String conversationPayload = String.format( - "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"%s\",\"conversationName\":\"E2E群\",\"subjectId\":%d}", + "{\"conversationType\":2,\"channelType\":\"wechat_personal\",\"conversationScene\":2,\"channelConversationId\":\"%s\",\"conversationName\":\"E2E群\",\"subjectId\":%d}", channelConversationId, subjectId); String conversationResponse = mockMvc.perform(post("/msg-platform/api/v1/conversation") .contextPath("/msg-platform") @@ -121,7 +132,7 @@ class SendEndToEndTest { .andExpect(jsonPath("$.data.length()").value(1)) .andExpect(jsonPath("$.data[0].taskId").value(taskId)) .andExpect(jsonPath("$.data[0].sendStatus").value(2)) - .andExpect(jsonPath("$.data[0].channelType").value("wecom")) + .andExpect(jsonPath("$.data[0].channelType").value("wechat_personal")) .andExpect(jsonPath("$.data[0].conversationId").value(conversationId)) .andExpect(jsonPath("$.data[0].accountId").value(accountId)) .andExpect(jsonPath("$.data[0].contentType").value("text")) diff --git a/backend/mci-server/src/test/java/com/sino/mci/send/service/SendServiceFailoverTest.java b/backend/mci-server/src/test/java/com/sino/mci/send/service/SendServiceFailoverTest.java index 14b1456..49fe749 100644 --- a/backend/mci-server/src/test/java/com/sino/mci/send/service/SendServiceFailoverTest.java +++ b/backend/mci-server/src/test/java/com/sino/mci/send/service/SendServiceFailoverTest.java @@ -115,9 +115,9 @@ class SendServiceFailoverTest { verify(adapter, times(2)).sendMessage(requestCaptor.capture()); List requests = requestCaptor.getAllValues(); assertEquals("wxid-primary", requests.get(0).getExtra().get("account_id")); - assertEquals(Integer.valueOf(3), requests.get(0).getExtra().get("account_type")); + assertEquals(Integer.valueOf(AccountType.WECHAT_PERSONAL.getCode()), requests.get(0).getExtra().get("account_type")); assertEquals("wxid-backup", requests.get(1).getExtra().get("account_id")); - assertEquals(Integer.valueOf(3), requests.get(1).getExtra().get("account_type")); + assertEquals(Integer.valueOf(AccountType.WECHAT_PERSONAL.getCode()), requests.get(1).getExtra().get("account_type")); ArgumentCaptor accountCaptor = ArgumentCaptor.forClass(ChannelAccount.class); verify(accountMapper, times(1)).updateById(accountCaptor.capture());