|
|
@@ -1,20 +1,34 @@
|
|
|
package com.fs.wx.sop.service.impl;
|
|
|
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-import com.fs.common.annotation.DataScope;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.fs.common.annotation.DataSource;
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.enums.DataSourceType;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.fs.sop.domain.QwSopLogs;
|
|
|
+import com.fs.common.utils.PubFun;
|
|
|
+import com.fs.common.utils.date.DateUtil;
|
|
|
+import com.fs.company.domain.CompanyWxAccount;
|
|
|
+import com.fs.company.mapper.CompanyWxAccountMapper;
|
|
|
+import com.fs.crm.domain.CrmCustomer;
|
|
|
+import com.fs.crm.mapper.CrmCustomerMapper;
|
|
|
+import com.fs.wx.sop.domain.WxSopLogs;
|
|
|
+import com.fs.wx.sop.domain.WxSopUser;
|
|
|
+import com.fs.wx.sop.domain.WxSopUserInfo;
|
|
|
+import com.fs.wx.sop.mapper.WxSopLogsMapper;
|
|
|
+import com.fs.wx.sop.mapper.WxSopUserInfoMapper;
|
|
|
+import com.fs.wx.sop.mapper.WxSopUserMapper;
|
|
|
+import com.fs.wx.sop.params.SendWxSopMsgParam;
|
|
|
import com.fs.wx.sop.params.WxSopLogsParam;
|
|
|
+import com.fs.wx.sop.service.IWxSopLogsService;
|
|
|
import com.fs.wx.sop.vo.WxSopLogsListVO;
|
|
|
+import com.fs.wxcid.domain.WxContact;
|
|
|
+import com.fs.wxcid.mapper.WxContactMapper;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-import com.fs.wx.sop.mapper.WxSopLogsMapper;
|
|
|
-import com.fs.wx.sop.domain.WxSopLogs;
|
|
|
-import com.fs.wx.sop.service.IWxSopLogsService;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 个微发送记录Service业务层处理
|
|
|
@@ -27,6 +41,18 @@ public class WxSopLogsServiceImpl extends ServiceImpl<WxSopLogsMapper, WxSopLogs
|
|
|
@Autowired
|
|
|
private WxSopLogsMapper wxSopLogsMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private WxSopUserMapper wxSopUserMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WxSopUserInfoMapper wxSopUserInfoMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWxAccountMapper companyWxAccountMapper;
|
|
|
+ @Autowired
|
|
|
+ private WxContactMapper wxContactMapper;
|
|
|
+ @Autowired
|
|
|
+ private CrmCustomerMapper crmCustomerMapper;
|
|
|
+
|
|
|
/**
|
|
|
* 查询个微发送记录
|
|
|
*
|
|
|
@@ -114,14 +140,178 @@ public class WxSopLogsServiceImpl extends ServiceImpl<WxSopLogsMapper, WxSopLogs
|
|
|
* @return 执行记录集合
|
|
|
*/
|
|
|
@Override
|
|
|
- @DataSource(DataSourceType.SOP)
|
|
|
- public List<WxSopLogsListVO> selectWxSopLogsListBySopId(WxSopLogsParam param)
|
|
|
- {
|
|
|
- return baseMapper.selectWxSopLogsListBySopId(param);
|
|
|
+ public List<WxSopLogsListVO> selectWxSopLogsListBySopId(WxSopLogsParam param){
|
|
|
+ List<WxSopLogsListVO> list = baseMapper.selectWxSopLogsListBySopId(param);
|
|
|
+ List<Long> longs = PubFun.listToNewList(list, WxSopLogsListVO::getAccountId);
|
|
|
+ List<CompanyWxAccount> companyWxAccounts = companyWxAccountMapper.selectBatchIds(longs);
|
|
|
+ Map<Long, CompanyWxAccount> accountMap = PubFun.listToMapByGroupObject(companyWxAccounts, CompanyWxAccount::getId);
|
|
|
+ list.parallelStream().filter(e -> accountMap.containsKey(e.getAccountId())).forEach(e -> {
|
|
|
+ e.setAccountName(accountMap.get(e.getAccountId()).getWxNickName());
|
|
|
+ });
|
|
|
+ return list;
|
|
|
}
|
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
public void batchInsertQwSopLogs(List<WxSopLogs> logsToInsert) {
|
|
|
if(logsToInsert == null || logsToInsert.isEmpty()) return;
|
|
|
wxSopLogsMapper.batchInsertWxSopLogs(logsToInsert);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 个微SOP一键群发
|
|
|
+ * 注意:不加 @DataSource(DataSourceType.SOP),因为需要跨库查询
|
|
|
+ * SOP相关Mapper方法自带 @DataSource(DataSourceType.SOP) 注解
|
|
|
+ * wx_contact、crm_customer 在主库,使用默认数据源
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public R sendWxSopMsg(SendWxSopMsgParam param) {
|
|
|
+ if (param.getSopIds() == null || param.getSopIds().length == 0) {
|
|
|
+ return R.error("请选择要群发的SOP");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 解析发送时间:前端选了就用前端的,没选就用当前时间
|
|
|
+ String sendTimeStr;
|
|
|
+ if (param.getSendTime() != null && !param.getSendTime().isEmpty()) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ sendTimeStr = sdf.format(new Date()) + " " + param.getSendTime() + ":00";
|
|
|
+ } else {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ sendTimeStr = sdf.format(new Date());
|
|
|
+ }
|
|
|
+
|
|
|
+ List<WxSopLogs> logsToInsert = new ArrayList<>();
|
|
|
+ // 收集所有联系人ID和客户ID,用于批量查询
|
|
|
+ List<Long> allContactIds = new ArrayList<>();
|
|
|
+ // 临时存储:sopUser + userInfos 的关系
|
|
|
+ List<Object[]> sopUserAndInfos = new ArrayList<>();
|
|
|
+
|
|
|
+ // 2. 遍历每个SOP,从SOP数据库查询营期和成员
|
|
|
+ for (Long sopId : param.getSopIds()) {
|
|
|
+ WxSopUser query = new WxSopUser();
|
|
|
+ query.setSopId(sopId);
|
|
|
+ // wxSopUserMapper.selectWxSopUserList 自带 @DataSource(DataSourceType.SOP)
|
|
|
+ List<WxSopUser> sopUsers = wxSopUserMapper.selectWxSopUserList(query);
|
|
|
+
|
|
|
+ if (sopUsers == null || sopUsers.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (WxSopUser sopUser : sopUsers) {
|
|
|
+ WxSopUserInfo userInfoQuery = new WxSopUserInfo();
|
|
|
+ userInfoQuery.setSopUserId(sopUser.getId());
|
|
|
+ // wxSopUserInfoMapper.selectWxSopUserInfoList 自带 @DataSource(DataSourceType.SOP)
|
|
|
+ List<WxSopUserInfo> userInfos = wxSopUserInfoMapper.selectWxSopUserInfoList(userInfoQuery);
|
|
|
+
|
|
|
+ if (userInfos == null || userInfos.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ sopUserAndInfos.add(new Object[]{sopId, sopUser, userInfos});
|
|
|
+
|
|
|
+ for (WxSopUserInfo info : userInfos) {
|
|
|
+ if (info.getWxContactId() != null) {
|
|
|
+ allContactIds.add(info.getWxContactId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sopUserAndInfos.isEmpty()) {
|
|
|
+ return R.error("未找到可群发的营期成员");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 从主库批量查询 wx_contact 获取联系人昵称
|
|
|
+ Map<Long, WxContact> contactMap = new HashMap<>();
|
|
|
+ Map<Long, CrmCustomer> customerMap = new HashMap<>();
|
|
|
+ if (!allContactIds.isEmpty()) {
|
|
|
+ List<Long> uniqueContactIds = allContactIds.stream().distinct().collect(Collectors.toList());
|
|
|
+ List<WxContact> contacts = wxContactMapper.selectBatchIds(uniqueContactIds);
|
|
|
+ if (contacts != null) {
|
|
|
+ for (WxContact c : contacts) {
|
|
|
+ contactMap.put(c.getId(), c);
|
|
|
+ }
|
|
|
+ // 4. 收集customerIds,从主库查询 crm_customer 获取客户标签
|
|
|
+ List<Long> customerIds = contacts.stream()
|
|
|
+ .filter(c -> c.getCustomerId() != null)
|
|
|
+ .map(WxContact::getCustomerId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!customerIds.isEmpty()) {
|
|
|
+ List<CrmCustomer> customers = crmCustomerMapper.selectBatchIds(customerIds);
|
|
|
+ if (customers != null) {
|
|
|
+ for (CrmCustomer cust : customers) {
|
|
|
+ customerMap.put(cust.getCustomerId(), cust);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 遍历构建发送记录,设置联系人昵称
|
|
|
+ // 同时收集需要更新标签的 userInfo
|
|
|
+ List<WxSopUserInfo> userInfosToUpdateTag = new ArrayList<>();
|
|
|
+ for (Object[] arr : sopUserAndInfos) {
|
|
|
+ Long sopId = (Long) arr[0];
|
|
|
+ WxSopUser sopUser = (WxSopUser) arr[1];
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ List<WxSopUserInfo> userInfos = (List<WxSopUserInfo>) arr[2];
|
|
|
+
|
|
|
+ for (WxSopUserInfo userInfo : userInfos) {
|
|
|
+ WxSopLogs log = new WxSopLogs();
|
|
|
+ log.setType(0);
|
|
|
+ log.setSopId(sopId);
|
|
|
+ log.setSopUserId(sopUser.getId());
|
|
|
+ log.setGenerateType(1);
|
|
|
+ log.setAccountId(sopUser.getAccountId());
|
|
|
+ log.setWxContactId(userInfo.getWxContactId());
|
|
|
+ log.setFsUserId(userInfo.getFsUserId());
|
|
|
+ log.setSendStatus(0);
|
|
|
+ log.setSendSort(30000000);
|
|
|
+ log.setContentJson(param.getSetting());
|
|
|
+ log.setSendTime(DateUtil.stringToLocalDateTime(sendTimeStr));
|
|
|
+ log.setCreateTime(new Date());
|
|
|
+
|
|
|
+ // 设置联系人昵称
|
|
|
+ WxContact contact = contactMap.get(userInfo.getWxContactId());
|
|
|
+ if (contact != null) {
|
|
|
+ log.setWxContactName(contact.getNickName());
|
|
|
+
|
|
|
+ // 更新 wx_sop_user_info 的标签(如果为空)
|
|
|
+ if ((userInfo.getTagNames() == null || userInfo.getTagNames().isEmpty())
|
|
|
+ && contact.getCustomerId() != null) {
|
|
|
+ CrmCustomer customer = customerMap.get(contact.getCustomerId());
|
|
|
+ if (customer != null && customer.getTags() != null && !customer.getTags().isEmpty()) {
|
|
|
+ userInfo.setTagNames(customer.getTags());
|
|
|
+ userInfosToUpdateTag.add(userInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ logsToInsert.add(log);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (logsToInsert.isEmpty()) {
|
|
|
+ return R.error("未找到可群发的营期成员");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 更新 wx_sop_user_info 的标签信息(SOP数据库)
|
|
|
+ for (WxSopUserInfo info : userInfosToUpdateTag) {
|
|
|
+ WxSopUserInfo updateInfo = new WxSopUserInfo();
|
|
|
+ updateInfo.setId(info.getId());
|
|
|
+ updateInfo.setTagNames(info.getTagNames());
|
|
|
+ wxSopUserInfoMapper.updateWxSopUserInfo(updateInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 批量插入发送记录到SOP数据库
|
|
|
+ batchInsertQwSopLogs(logsToInsert);
|
|
|
+
|
|
|
+ return R.ok("一键群发成功,共发送 " + logsToInsert.size() + " 条消息");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
+ public boolean updateMapper(WxSopLogs updateQwSop) {
|
|
|
+ return updateById(updateQwSop);
|
|
|
+ }
|
|
|
}
|