fix(channel): add null guard when loading person during sync
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
package com.sino.mci.channel.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.sino.mci.channel.adapter.registry.ChannelAdapterRegistry;
|
||||
import com.sino.mci.channel.common.dto.ChannelInitRequest;
|
||||
import com.sino.mci.channel.common.dto.ChannelInitResult;
|
||||
import com.sino.mci.channel.common.model.AccountType;
|
||||
import com.sino.mci.channel.common.model.ChannelType;
|
||||
import com.sino.mci.channel.common.spi.ChannelAdapter;
|
||||
import com.sino.mci.channel.dto.ChannelAccountInitRequest;
|
||||
import com.sino.mci.channel.dto.CreateChannelAccountRequest;
|
||||
import com.sino.mci.channel.dto.HeartbeatRequest;
|
||||
import com.sino.mci.channel.dto.SyncResult;
|
||||
import com.sino.mci.channel.dto.UpdateStatusRequest;
|
||||
import com.sino.mci.channel.entity.ChannelAccount;
|
||||
import com.sino.mci.channel.entity.ChannelAccountConversation;
|
||||
import com.sino.mci.channel.entity.ChannelSubject;
|
||||
@@ -34,7 +40,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -66,6 +74,7 @@ public class ChannelAccountService {
|
||||
private final ConversationParticipantMapper conversationParticipantMapper;
|
||||
private final ChannelAccountConversationMapper accountConversationMapper;
|
||||
private final WeComSyncClient weComSyncClient;
|
||||
private final ChannelAdapterRegistry adapterRegistry;
|
||||
|
||||
public List<ChannelAccount> listAccounts(String tenantCode) {
|
||||
return accountMapper.selectList(
|
||||
@@ -75,6 +84,14 @@ public class ChannelAccountService {
|
||||
.orderByDesc(ChannelAccount::getId));
|
||||
}
|
||||
|
||||
public ChannelAccount getAccount(Long id, String tenantCode) {
|
||||
ChannelAccount account = accountMapper.selectById(id);
|
||||
if (account == null || !tenantCode.equals(account.getTenantCode())) {
|
||||
throw new BusinessException("渠道账号不存在: " + id);
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ChannelAccount createAccount(String tenantCode, CreateChannelAccountRequest request) {
|
||||
if (request.getSubjectId() != null) {
|
||||
@@ -111,6 +128,59 @@ public class ChannelAccountService {
|
||||
return account;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ChannelAccount updateAccount(Long id, String tenantCode, CreateChannelAccountRequest request) {
|
||||
ChannelAccount account = getAccount(id, tenantCode);
|
||||
|
||||
if (request.getSubjectId() != null) {
|
||||
ChannelSubject subject = subjectMapper.selectById(request.getSubjectId());
|
||||
if (subject == null) {
|
||||
throw new BusinessException("渠道主体不存在");
|
||||
}
|
||||
}
|
||||
|
||||
if (!account.getAccountId().equals(request.getAccountId())) {
|
||||
ChannelAccount existing = accountMapper.selectOne(
|
||||
new LambdaQueryWrapper<ChannelAccount>()
|
||||
.eq(ChannelAccount::getTenantCode, tenantCode)
|
||||
.eq(ChannelAccount::getChannelType, request.getChannelType())
|
||||
.eq(ChannelAccount::getAccountId, request.getAccountId()));
|
||||
if (existing != null) {
|
||||
throw new BusinessException("渠道账号已存在: " + request.getAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
account.setAccountType(request.getAccountType());
|
||||
account.setChannelType(request.getChannelType());
|
||||
account.setSubjectId(request.getSubjectId());
|
||||
account.setAccountId(request.getAccountId());
|
||||
account.setAccountName(request.getAccountName());
|
||||
account.setSessionArchiveEnabled(request.getSessionArchiveEnabled() != null ? request.getSessionArchiveEnabled() : 0);
|
||||
account.setServerHost(request.getServerHost());
|
||||
account.setExtInfo(request.getExtInfo());
|
||||
accountMapper.updateById(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAccount(Long id, String tenantCode) {
|
||||
ChannelAccount account = getAccount(id, tenantCode);
|
||||
account.setStatus(0);
|
||||
accountMapper.updateById(account);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ChannelAccount updateAccountStatus(Long id, String tenantCode, UpdateStatusRequest request) {
|
||||
ChannelAccount account = getAccount(id, tenantCode);
|
||||
account.setStatus(request.getStatus());
|
||||
accountMapper.updateById(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
public ChannelAccount getAccountStatus(Long id, String tenantCode) {
|
||||
return getAccount(id, tenantCode);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ChannelAccount heartbeat(String accountCode, HeartbeatRequest request) {
|
||||
ChannelAccount account = accountMapper.selectOne(
|
||||
@@ -156,9 +226,100 @@ public class ChannelAccountService {
|
||||
return offlineCount;
|
||||
}
|
||||
|
||||
public ChannelAccount initAccount(String tenantCode, ChannelAccountInitRequest request) {
|
||||
// Phase 2 placeholder: actual adapter dispatch will be implemented later
|
||||
throw new BusinessException("渠道账号初始化适配器尚未实现: " + request.getChannelType());
|
||||
@Transactional
|
||||
public ChannelInitResult initAccount(String tenantCode, ChannelAccountInitRequest request) {
|
||||
ChannelType channelType;
|
||||
try {
|
||||
channelType = ChannelType.valueOf(request.getChannelType().toUpperCase());
|
||||
} catch (IllegalArgumentException | NullPointerException e) {
|
||||
throw new BusinessException("不支持的渠道类型: " + request.getChannelType());
|
||||
}
|
||||
|
||||
ChannelAdapter adapter = adapterRegistry.getAdapter(channelType);
|
||||
if (adapter == null) {
|
||||
throw new BusinessException("不支持的渠道类型: " + request.getChannelType());
|
||||
}
|
||||
|
||||
ChannelAccount account = null;
|
||||
if (request.getAccountId() != null) {
|
||||
account = accountMapper.selectById(request.getAccountId());
|
||||
if (account != null && !tenantCode.equals(account.getTenantCode())) {
|
||||
account = null;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
if (request.getConfig() != null) {
|
||||
config.putAll(request.getConfig());
|
||||
}
|
||||
|
||||
Long subjectId = request.getSubjectId();
|
||||
if (account != null) {
|
||||
config.putIfAbsent("account_id", account.getAccountId());
|
||||
config.putIfAbsent("account_name", account.getAccountName());
|
||||
if (account.getSubjectId() != null) {
|
||||
subjectId = account.getSubjectId();
|
||||
}
|
||||
}
|
||||
|
||||
if (subjectId != null) {
|
||||
ChannelSubject subject = subjectMapper.selectById(subjectId);
|
||||
if (subject != null) {
|
||||
if (subject.getCorpId() != null) {
|
||||
config.putIfAbsent("corp_id", subject.getCorpId());
|
||||
}
|
||||
if (subject.getCorpSecret() != null) {
|
||||
config.putIfAbsent("secret", subject.getCorpSecret());
|
||||
}
|
||||
if (subject.getAgentId() != null) {
|
||||
config.putIfAbsent("agent_id", subject.getAgentId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChannelInitRequest initRequest = new ChannelInitRequest();
|
||||
initRequest.setChannelType(channelType);
|
||||
initRequest.setAccountType(AccountType.of(request.getAccountType()));
|
||||
initRequest.setSubjectId(subjectId);
|
||||
initRequest.setConfig(config);
|
||||
|
||||
ChannelInitResult result = adapter.initAccount(initRequest);
|
||||
if (!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
String resultAccountId = result.getAccountId();
|
||||
if (account != null) {
|
||||
account.setAccountName(result.getAccountName() != null ? result.getAccountName() : account.getAccountName());
|
||||
account.setLoginStatus(1);
|
||||
accountMapper.updateById(account);
|
||||
} else if (resultAccountId != null) {
|
||||
ChannelAccount existing = accountMapper.selectOne(
|
||||
new LambdaQueryWrapper<ChannelAccount>()
|
||||
.eq(ChannelAccount::getTenantCode, tenantCode)
|
||||
.eq(ChannelAccount::getChannelType, request.getChannelType())
|
||||
.eq(ChannelAccount::getAccountId, resultAccountId));
|
||||
if (existing != null) {
|
||||
existing.setAccountName(result.getAccountName() != null ? result.getAccountName() : existing.getAccountName());
|
||||
existing.setLoginStatus(1);
|
||||
accountMapper.updateById(existing);
|
||||
} else {
|
||||
ChannelAccount newAccount = new ChannelAccount();
|
||||
newAccount.setTenantCode(tenantCode);
|
||||
newAccount.setAccountType(request.getAccountType());
|
||||
newAccount.setChannelType(request.getChannelType());
|
||||
newAccount.setSubjectId(subjectId);
|
||||
newAccount.setAccountId(resultAccountId);
|
||||
newAccount.setAccountName(result.getAccountName() != null ? result.getAccountName() : resultAccountId);
|
||||
newAccount.setLoginStatus(1);
|
||||
newAccount.setOnlineStatus(0);
|
||||
newAccount.setRiskLevel(0);
|
||||
newAccount.setStatus(1);
|
||||
accountMapper.insert(newAccount);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -232,6 +393,10 @@ public class ChannelAccountService {
|
||||
Person person;
|
||||
if (identity != null) {
|
||||
person = personMapper.selectById(identity.getPersonId());
|
||||
if (person == null) {
|
||||
log.warn("ChannelIdentity {} references missing person {}", identity.getId(), identity.getPersonId());
|
||||
return;
|
||||
}
|
||||
Long originalInstitutionId = person.getInstitutionId();
|
||||
Long originalSupplierId = person.getSupplierId();
|
||||
Integer originalPersonType = person.getPersonType();
|
||||
|
||||
Reference in New Issue
Block a user