fix(send-routing): address final review findings
- Persist conversationScene in create/update conversation - Make bindAccount validate by conversation scene (1=WECOM_BOT, 2=WECHAT_PERSONAL) - Re-derive channelType from conversation_scene in dispatchRecord - Check WeCom response errcode and HTTP status in WeComBotSender - Support custom webhook_url from ext_info in WeComBotSender - Configure RestTemplate with 5s connect / 10s read timeouts - Expand WeComBotSenderTest with MockRestServiceServer coverage
This commit is contained in:
@@ -21,6 +21,7 @@ public class CreateConversationRequest {
|
||||
private Long ownerAccountId;
|
||||
private Long subjectId;
|
||||
private String conversationName;
|
||||
private Integer conversationScene;
|
||||
private Integer createSource;
|
||||
private Map<String, Object> receiveConfig;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public class UpdateConversationRequest {
|
||||
|
||||
private Long ownerAccountId;
|
||||
private Long subjectId;
|
||||
private Integer conversationScene;
|
||||
private Integer status;
|
||||
private Map<String, Object> receiveConfig;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.sino.mci.channel.dto.UpdateConversationRequest;
|
||||
import com.sino.mci.channel.entity.ChannelAccount;
|
||||
import com.sino.mci.channel.entity.ChannelAccountConversation;
|
||||
import com.sino.mci.channel.entity.Conversation;
|
||||
import com.sino.mci.channel.common.model.AccountType;
|
||||
import com.sino.mci.channel.entity.ConversationParticipant;
|
||||
import com.sino.mci.channel.entity.ConversationTagBinding;
|
||||
import com.sino.mci.channel.repository.ChannelAccountConversationMapper;
|
||||
@@ -78,6 +79,7 @@ public class ConversationService {
|
||||
conversation.setOwnerAccountId(request.getOwnerAccountId());
|
||||
conversation.setSubjectId(request.getSubjectId());
|
||||
conversation.setConversationName(request.getConversationName());
|
||||
conversation.setConversationScene(request.getConversationScene());
|
||||
conversation.setCreateSource(request.getCreateSource() != null ? request.getCreateSource() : 2);
|
||||
conversation.setReceiveConfig(JsonUtils.toJson(request.getReceiveConfig()));
|
||||
conversation.setStatus(1);
|
||||
@@ -109,6 +111,9 @@ public class ConversationService {
|
||||
if (request.getReceiveConfig() != null) {
|
||||
conversation.setReceiveConfig(JsonUtils.toJson(request.getReceiveConfig()));
|
||||
}
|
||||
if (request.getConversationScene() != null) {
|
||||
conversation.setConversationScene(request.getConversationScene());
|
||||
}
|
||||
conversationMapper.updateById(conversation);
|
||||
return conversation;
|
||||
}
|
||||
@@ -127,7 +132,7 @@ public class ConversationService {
|
||||
if (account == null || !tenantCode.equals(account.getTenantCode())) {
|
||||
throw new BusinessException("账号不存在或不在当前租户");
|
||||
}
|
||||
if (!conversation.getChannelType().equalsIgnoreCase(account.getChannelType())) {
|
||||
if (!isAccountCompatibleWithConversation(conversation, account)) {
|
||||
throw new BusinessException("账号渠道类型与会话不一致");
|
||||
}
|
||||
|
||||
@@ -144,6 +149,24 @@ public class ConversationService {
|
||||
binding.setSortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0);
|
||||
binding.setStatus(1);
|
||||
bindingMapper.insert(binding);
|
||||
|
||||
// 主发送账号作为会话负责人
|
||||
if (request.getBindingType() != null && request.getBindingType() == 1) {
|
||||
conversation.setOwnerAccountId(request.getAccountId());
|
||||
conversationMapper.updateById(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAccountCompatibleWithConversation(Conversation conversation, ChannelAccount account) {
|
||||
Integer scene = conversation.getConversationScene();
|
||||
if (scene != null) {
|
||||
return switch (scene) {
|
||||
case 1 -> AccountType.WECOM_BOT.getCode() == account.getAccountType();
|
||||
case 2 -> AccountType.WECHAT_PERSONAL.getCode() == account.getAccountType();
|
||||
default -> conversation.getChannelType().equalsIgnoreCase(account.getChannelType());
|
||||
};
|
||||
}
|
||||
return conversation.getChannelType().equalsIgnoreCase(account.getChannelType());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -853,6 +853,22 @@ public class SendService {
|
||||
public void dispatchRecord(SendRecord record) {
|
||||
|
||||
ChannelType channelType = parseChannelType(record.getChannelType());
|
||||
Set<Integer> accountTypes;
|
||||
if (record.getConversationId() != null) {
|
||||
Conversation conversation = conversationMapper.selectById(record.getConversationId());
|
||||
Integer scene = conversation != null ? conversation.getConversationScene() : null;
|
||||
if (scene != null) {
|
||||
channelType = resolveChannelTypeForScene(scene);
|
||||
accountTypes = resolveAccountTypesForScene(scene);
|
||||
} else {
|
||||
accountTypes = null;
|
||||
}
|
||||
} else if (record.getPersonId() != null) {
|
||||
accountTypes = ACCOUNT_TYPES_WECOM_AGENT;
|
||||
} else {
|
||||
accountTypes = null;
|
||||
}
|
||||
|
||||
ChannelAdapter adapter = adapterRegistry.getAdapter(channelType);
|
||||
if (adapter == null) {
|
||||
record.setSendStatus(SEND_STATUS_FAILED);
|
||||
@@ -875,15 +891,6 @@ public class SendService {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> accountTypes;
|
||||
if (record.getConversationId() != null) {
|
||||
Conversation conversation = conversationMapper.selectById(record.getConversationId());
|
||||
accountTypes = resolveAccountTypesForScene(conversation != null ? conversation.getConversationScene() : null);
|
||||
} else if (record.getPersonId() != null) {
|
||||
accountTypes = ACCOUNT_TYPES_WECOM_AGENT;
|
||||
} else {
|
||||
accountTypes = null;
|
||||
}
|
||||
List<Long> candidateAccountIds = selectSendAccountCandidates(record, channelType, accountTypes);
|
||||
if (candidateAccountIds.isEmpty()) {
|
||||
record.setSendStatus(SEND_STATUS_FAILED);
|
||||
|
||||
Reference in New Issue
Block a user