|
@@ -12,14 +12,21 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.fs.ad.enums.AdUploadType;
|
|
import com.fs.ad.enums.AdUploadType;
|
|
|
import com.fs.ad.service.IAdHtmlClickLogService;
|
|
import com.fs.ad.service.IAdHtmlClickLogService;
|
|
|
|
|
+import com.fs.common.constant.Constants;
|
|
|
import com.fs.common.core.domain.R;
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
import com.fs.common.utils.CloudHostUtils;
|
|
import com.fs.common.utils.CloudHostUtils;
|
|
|
import com.fs.common.utils.PubFun;
|
|
import com.fs.common.utils.PubFun;
|
|
|
import com.fs.common.utils.StringUtils;
|
|
import com.fs.common.utils.StringUtils;
|
|
|
|
|
+import com.fs.company.domain.CompanyVoiceRoboticCallLogAddwx;
|
|
|
import com.fs.company.domain.CompanyWxAccount;
|
|
import com.fs.company.domain.CompanyWxAccount;
|
|
|
|
|
+import com.fs.company.domain.CompanyWxClient;
|
|
|
import com.fs.company.mapper.CompanyWxAccountMapper;
|
|
import com.fs.company.mapper.CompanyWxAccountMapper;
|
|
|
|
|
+import com.fs.company.mapper.CompanyWxClientMapper;
|
|
|
import com.fs.company.service.ICompanyConfigService;
|
|
import com.fs.company.service.ICompanyConfigService;
|
|
|
|
|
+import com.fs.company.service.ICompanyVoiceRoboticCallLogAddwxService;
|
|
|
|
|
+import com.fs.company.service.impl.CompanyWxServiceImpl;
|
|
|
|
|
+import com.fs.company.vo.CidQwAddWxPendingVO;
|
|
|
import com.fs.config.cloud.CloudHostProper;
|
|
import com.fs.config.cloud.CloudHostProper;
|
|
|
import com.fs.course.domain.FsCourseSop;
|
|
import com.fs.course.domain.FsCourseSop;
|
|
|
import com.fs.course.domain.FsCourseSopLogs;
|
|
import com.fs.course.domain.FsCourseSopLogs;
|
|
@@ -37,6 +44,8 @@ import com.fs.his.domain.FsUser;
|
|
|
import com.fs.his.mapper.FsUserMapper;
|
|
import com.fs.his.mapper.FsUserMapper;
|
|
|
import com.fs.his.utils.PhoneUtil;
|
|
import com.fs.his.utils.PhoneUtil;
|
|
|
import com.fs.hisStore.vo.FsStoreOrderScrmSidebarVO;
|
|
import com.fs.hisStore.vo.FsStoreOrderScrmSidebarVO;
|
|
|
|
|
+import com.fs.ipad.IpadSendUtils;
|
|
|
|
|
+import com.fs.ipad.vo.BaseVo;
|
|
|
import com.fs.qw.domain.*;
|
|
import com.fs.qw.domain.*;
|
|
|
import com.fs.qw.mapper.*;
|
|
import com.fs.qw.mapper.*;
|
|
|
import com.fs.qw.param.*;
|
|
import com.fs.qw.param.*;
|
|
@@ -72,6 +81,10 @@ import com.fs.sop.service.ISopUserLogsService;
|
|
|
import com.fs.system.service.ISysConfigService;
|
|
import com.fs.system.service.ISysConfigService;
|
|
|
import com.fs.system.service.ISysDictTypeService;
|
|
import com.fs.system.service.ISysDictTypeService;
|
|
|
import com.fs.voice.utils.StringUtil;
|
|
import com.fs.voice.utils.StringUtil;
|
|
|
|
|
+import com.fs.wxwork.dto.WxLoginDTO;
|
|
|
|
|
+import com.fs.wxwork.dto.WxLoginResp;
|
|
|
|
|
+import com.fs.wxwork.dto.WxWorkResponseDTO;
|
|
|
|
|
+import com.fs.wxwork.service.WxWorkServiceNew;
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.Gson;
|
|
|
import com.google.gson.reflect.TypeToken;
|
|
import com.google.gson.reflect.TypeToken;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -225,9 +238,22 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
@Autowired
|
|
@Autowired
|
|
|
QwAcquisitionAssistantMapper acquisitionAssistantMapper;
|
|
QwAcquisitionAssistantMapper acquisitionAssistantMapper;
|
|
|
|
|
|
|
|
|
|
+
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private AsyncQwContactWayService asyncQwContactWayService;
|
|
private AsyncQwContactWayService asyncQwContactWayService;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WxWorkServiceNew wxWorkServiceNew;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private IpadSendUtils ipadSendUtils;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CompanyWxClientMapper companyWxClientMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private ICompanyVoiceRoboticCallLogAddwxService companyVoiceRoboticCallLogAddwxService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CompanyWxServiceImpl companyWxServiceImpl;
|
|
|
|
|
+
|
|
|
Logger logger = LoggerFactory.getLogger(getClass());
|
|
Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private CompanyWxAccountMapper companyWxAccountMapper;
|
|
private CompanyWxAccountMapper companyWxAccountMapper;
|
|
@@ -3050,6 +3076,9 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
//上面存过了,这里就更新
|
|
//上面存过了,这里就更新
|
|
|
qwExternalContact.setId(contact.getId());
|
|
qwExternalContact.setId(contact.getId());
|
|
|
qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
|
|
qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
|
|
|
|
|
+ //cid 回调处理
|
|
|
|
|
+ handleCidQwAddWxAfterContactSaved(qwUser, contact.getId(), externalUserID);
|
|
|
|
|
+
|
|
|
QwOpenidByExternalcontactParams externalcontactParams = new QwOpenidByExternalcontactParams();
|
|
QwOpenidByExternalcontactParams externalcontactParams = new QwOpenidByExternalcontactParams();
|
|
|
externalcontactParams.setExternal_userid(externalUserID);
|
|
externalcontactParams.setExternal_userid(externalUserID);
|
|
|
//录入单独的CRM客户信息 没啥用
|
|
//录入单独的CRM客户信息 没啥用
|
|
@@ -3086,6 +3115,115 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 外部联系人入库后:解析 ipadUserId,匹配 CID 加微 Redis 并触发工作流
|
|
|
|
|
+ */
|
|
|
|
|
+ private void handleCidQwAddWxAfterContactSaved(QwUser qwUser, Long externalContactId, String externalUserId) {
|
|
|
|
|
+ if (qwUser == null || externalContactId == null || StringUtils.isBlank(externalUserId)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+
|
|
|
|
|
+ Long ipadUserId = resolveIpadUserIdByExternalUserId(qwUser, externalUserId);
|
|
|
|
|
+ if (ipadUserId == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ QwExternalContact ipadUpdate = new QwExternalContact();
|
|
|
|
|
+ ipadUpdate.setId(externalContactId);
|
|
|
|
|
+ ipadUpdate.setIpadUserId(ipadUserId);
|
|
|
|
|
+ qwExternalContactMapper.updateQwExternalContact(ipadUpdate);
|
|
|
|
|
+
|
|
|
|
|
+ String redisKey = Constants.cidQwAddWxSearchUserIdKey(ipadUserId);
|
|
|
|
|
+ CidQwAddWxPendingVO pending = redisCache.getCacheObject(redisKey);
|
|
|
|
|
+ if (pending == null || pending.getWxClientId() == null) {
|
|
|
|
|
+ log.debug("CID加微未命中 Redis, ipadUserId={}, externalUserId={}",
|
|
|
|
|
+ ipadUserId, externalUserId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (pending.getAccountId() != null && !pending.getAccountId().equals(qwUser.getId())) {
|
|
|
|
|
+ log.info("CID加微 Redis 账号不匹配, pendingAccountId={}, qwUserId={}, ipadUserId={}",
|
|
|
|
|
+ pending.getAccountId(), qwUser.getId(), ipadUserId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ CompanyWxClient wxClient = companyWxClientMapper.selectById(pending.getWxClientId());
|
|
|
|
|
+ if (wxClient == null) {
|
|
|
|
|
+ log.info("CID加微待处理客户不存在, wxClientId={}", pending.getWxClientId());
|
|
|
|
|
+ redisCache.deleteObject(redisKey);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Integer.valueOf(1).equals(wxClient.getIsAdd())) {
|
|
|
|
|
+ redisCache.deleteObject(redisKey);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ wxClient.setIsAdd(1);
|
|
|
|
|
+ wxClient.setSuccessAddTime(LocalDateTime.now());
|
|
|
|
|
+ companyWxClientMapper.updateById(wxClient);
|
|
|
|
|
+
|
|
|
|
|
+ companyVoiceRoboticCallLogAddwxService.lambdaUpdate()
|
|
|
|
|
+ .eq(CompanyVoiceRoboticCallLogAddwx::getRoboticId, wxClient.getRoboticId())
|
|
|
|
|
+ .eq(CompanyVoiceRoboticCallLogAddwx::getWxClientId, wxClient.getId())
|
|
|
|
|
+ .eq(CompanyVoiceRoboticCallLogAddwx::getWxAccountId, wxClient.getAccountId())
|
|
|
|
|
+ .eq(CompanyVoiceRoboticCallLogAddwx::getIsWeCom, 2)
|
|
|
|
|
+ .set(CompanyVoiceRoboticCallLogAddwx::getStatus, 2)
|
|
|
|
|
+ .update();
|
|
|
|
|
+
|
|
|
|
|
+ redisCache.deleteObject(redisKey);
|
|
|
|
|
+ redisCache.deleteObject(Constants.QW_ADD_WX + "_" + wxClient.getId());
|
|
|
|
|
+
|
|
|
|
|
+ companyWxServiceImpl.triggerQwAddWxWorkflowOnSuccess(wxClient.getId());
|
|
|
|
|
+ log.info("CID企微加微回调匹配成功, wxClientId={}, ipadUserId={}, externalUserId={}",
|
|
|
|
|
+ wxClient.getId(), ipadUserId, externalUserId);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.info("CID企微加微回调处理异常, externalContactId={}, externalUserId={}", externalContactId, externalUserId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 外部联系人 externalUserId 转 iPad 侧 user_id(复用 IpadSendUtils.userIds,含 appId 解析)
|
|
|
|
|
+ */
|
|
|
|
|
+ private Long resolveIpadUserIdByExternalUserId(QwUser qwUser, String externalUserId) {
|
|
|
|
|
+ if (qwUser.getServerId() == null || StringUtils.isBlank(qwUser.getUid()) || StringUtils.isBlank(qwUser.getCorpId())) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ WxLoginDTO loginDto = new WxLoginDTO();
|
|
|
|
|
+ loginDto.setUuid(qwUser.getUid());
|
|
|
|
|
+ WxWorkResponseDTO<WxLoginResp> loginResult = wxWorkServiceNew.isLogin(loginDto, qwUser.getServerId());
|
|
|
|
|
+ if (loginResult == null || loginResult.getErrcode() != 0 || loginResult.getData() == null
|
|
|
|
|
+ || loginResult.getData().getUser_info() == null
|
|
|
|
|
+ || loginResult.getData().getUser_info().getObject() == null) {
|
|
|
|
|
+ log.warn("CID加微解析 ipadUserId 失败:企微 iPad 未登录, qwUserId={}", qwUser.getId());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ String corpCode = loginResult.getData().getUser_info().getObject().getScorp_id();
|
|
|
|
|
+ QwCompany qwCompany = iQwCompanyService.getQwCompanyByRedis(qwUser.getCorpId());
|
|
|
|
|
+ if (qwCompany == null || StringUtils.isBlank(qwCompany.getServerAgentId())) {
|
|
|
|
|
+ log.warn("CID加微解析 ipadUserId 失败:未配置 serverAgentId, corpId={}, qwUserId={}",
|
|
|
|
|
+ qwUser.getCorpId(), qwUser.getId());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ BaseVo baseVo = new BaseVo();
|
|
|
|
|
+ baseVo.setUuid(qwUser.getUid());
|
|
|
|
|
+ baseVo.setServerId(qwUser.getServerId());
|
|
|
|
|
+ baseVo.setCorpId(qwUser.getCorpId());
|
|
|
|
|
+ baseVo.setCorpCode(corpCode);
|
|
|
|
|
+ baseVo.setExId(externalUserId);
|
|
|
|
|
+ baseVo.setQwUserId(qwUser.getId());
|
|
|
|
|
+ return ipadSendUtils.userIds(baseVo);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("CID加微 externalUserId 转 ipadUserId 失败, externalUserId={}, qwUserId={}, err={}",
|
|
|
|
|
+ externalUserId, qwUser.getId(), e.getMessage());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private long getSecondsUntilMidnight() {
|
|
private long getSecondsUntilMidnight() {
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
|
|
LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
|