|
@@ -0,0 +1,559 @@
|
|
|
|
|
+package com.fs.wx.sop.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import com.fs.common.annotation.DataSource;
|
|
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
|
|
+import com.fs.common.core.domain.entity.SysDictData;
|
|
|
|
|
+import com.fs.common.enums.DataSourceType;
|
|
|
|
|
+import com.fs.crm.domain.CrmCustomer;
|
|
|
|
|
+import com.fs.crm.mapper.CrmCustomerMapper;
|
|
|
|
|
+import com.fs.sop.params.WxSopTagsParam;
|
|
|
|
|
+import com.fs.sop.vo.WxFilterSopCustomersResult;
|
|
|
|
|
+import com.fs.system.service.ISysDictDataService;
|
|
|
|
|
+import com.fs.wx.sop.domain.WxSop;
|
|
|
|
|
+import com.fs.wx.sop.domain.WxSopUser;
|
|
|
|
|
+import com.fs.wx.sop.domain.WxSopUserInfo;
|
|
|
|
|
+import com.fs.wx.sop.mapper.WxSopMapper;
|
|
|
|
|
+import com.fs.wx.sop.mapper.WxSopUserInfoMapper;
|
|
|
|
|
+import com.fs.wx.sop.mapper.WxSopUserMapper;
|
|
|
|
|
+import com.fs.wx.sop.service.IWxSopExecuteService;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
+
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 个微SOP执行服务实现类
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author fs
|
|
|
|
|
+ * @date 2025-03-12
|
|
|
|
|
+ */
|
|
|
|
|
+@Service
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class WxSopExecuteServiceImpl implements IWxSopExecuteService {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WxSopMapper wxSopMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WxSopUserMapper wxSopUserMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WxSopUserInfoMapper wxSopUserInfoMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CrmCustomerMapper crmCustomerMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private ISysDictDataService sysDictDataService;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public R processTagFilterWxSop(WxSop wxSop) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ log.info("====== 开始执行标签筛选SOP ======");
|
|
|
|
|
+ log.info("SOP ID: {}, 名称: {}, 筛选标签: {}, 执行账号: {}",
|
|
|
|
|
+ wxSop.getId(), wxSop.getName(), wxSop.getSelectTags(), wxSop.getAccountIds());
|
|
|
|
|
+
|
|
|
|
|
+ // 构建标签筛选参数
|
|
|
|
|
+ WxSopTagsParam wxSopTagsParam = buildWxSopTagsParam(wxSop);
|
|
|
|
|
+ log.info("筛选参数: accountIds={}, tags={}, excludeTags={}",
|
|
|
|
|
+ wxSopTagsParam.getAccountIdsSelectList(),
|
|
|
|
|
+ wxSopTagsParam.getTagsIdsSelectList(),
|
|
|
|
|
+ wxSopTagsParam.getOutTagsIdsSelectList());
|
|
|
|
|
+
|
|
|
|
|
+ // 查询符合条件的客户
|
|
|
|
|
+ List<WxFilterSopCustomersResult> customerResults = selectFilterWxSopCustomers(wxSopTagsParam);
|
|
|
|
|
+ log.info("查询到的客户数量: {}", customerResults != null ? customerResults.size() : 0);
|
|
|
|
|
+
|
|
|
|
|
+ if (customerResults != null && !customerResults.isEmpty()) {
|
|
|
|
|
+ for (WxFilterSopCustomersResult customer : customerResults) {
|
|
|
|
|
+ log.info("符合条件的客户: ID={}, 名称={}, 账号ID={}",
|
|
|
|
|
+ customer.getId(), customer.getName(), customer.getAccountId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (customerResults == null || customerResults.isEmpty()) {
|
|
|
|
|
+ log.warn("未找到符合条件的客户,SOP ID: {}", wxSop.getId());
|
|
|
|
|
+ return R.error("未找到符合条件的客户");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 为客户创建营期记录
|
|
|
|
|
+ createSopUserLogsWxForCustomers(wxSop, customerResults);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("标签筛选SOP处理完成,SOP ID: {},客户数量: {}", wxSop.getId(), customerResults.size());
|
|
|
|
|
+ return R.ok("标签筛选SOP处理完成");
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理标签筛选SOP时发生异常,SOP ID: {}", wxSop.getId(), e);
|
|
|
|
|
+ return R.error("处理过程中发生异常: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public R processGroupFilterWxSop(WxSop wxSop) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 群聊筛选逻辑
|
|
|
|
|
+ // 这里需要根据群聊ID或其他群聊相关信息筛选客户
|
|
|
|
|
+ // 暂时留空实现,需要根据具体业务需求完善
|
|
|
|
|
+
|
|
|
|
|
+ log.info("群聊筛选SOP处理完成,SOP ID: {}", wxSop.getId());
|
|
|
|
|
+ return R.ok("群聊筛选SOP处理完成");
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理群聊筛选SOP时发生异常,SOP ID: {}", wxSop.getId(), e);
|
|
|
|
|
+ return R.error("处理过程中发生异常: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public R createSopUserLogsWx(WxSop wxSop) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 根据SOP的筛选方式进行不同的客户筛选
|
|
|
|
|
+ if (wxSop.getFilterType() != null && wxSop.getFilterType() == 0) { // 0: 标签筛选
|
|
|
|
|
+ return processTagFilterWxSop(wxSop);
|
|
|
|
|
+ } else if (wxSop.getFilterType() != null && wxSop.getFilterType() == 1) { // 1: 群聊筛选
|
|
|
|
|
+ return processGroupFilterWxSop(wxSop);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return R.error("未知的筛选方式");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("创建SOP营期记录时发生异常,SOP ID: {}", wxSop.getId(), e);
|
|
|
|
|
+ return R.error("创建营期记录时发生异常: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建标签筛选参数
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param wxSop 个微SOP
|
|
|
|
|
+ * @return 标签筛选参数
|
|
|
|
|
+ */
|
|
|
|
|
+ private WxSopTagsParam buildWxSopTagsParam(WxSop wxSop) {
|
|
|
|
|
+ WxSopTagsParam param = new WxSopTagsParam();
|
|
|
|
|
+
|
|
|
|
|
+ // 设置执行账号ID列表
|
|
|
|
|
+ if (wxSop.getAccountIds() != null && !wxSop.getAccountIds().isEmpty()) {
|
|
|
|
|
+ String[] accountIds = wxSop.getAccountIds().split(",");
|
|
|
|
|
+ List<String> accountIdsList = new ArrayList<>();
|
|
|
|
|
+ for (String accountId : accountIds) {
|
|
|
|
|
+ if (accountId != null && !accountId.trim().isEmpty()) {
|
|
|
|
|
+ accountIdsList.add(accountId.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ param.setAccountIdsSelectList(accountIdsList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置筛选标签
|
|
|
|
|
+ if (wxSop.getSelectTags() != null && !wxSop.getSelectTags().isEmpty()) {
|
|
|
|
|
+ String[] tags = wxSop.getSelectTags().split(",");
|
|
|
|
|
+ List<String> tagsList = new ArrayList<>();
|
|
|
|
|
+ for (String tag : tags) {
|
|
|
|
|
+ if (tag != null && !tag.trim().isEmpty()) {
|
|
|
|
|
+ tagsList.add(tag.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ param.setTagsIdsSelectList(tagsList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置排除标签
|
|
|
|
|
+ if (wxSop.getExcludeTags() != null && !wxSop.getExcludeTags().isEmpty()) {
|
|
|
|
|
+ String[] excludeTags = wxSop.getExcludeTags().split(",");
|
|
|
|
|
+ List<String> excludeTagsList = new ArrayList<>();
|
|
|
|
|
+ for (String excludeTag : excludeTags) {
|
|
|
|
|
+ if (excludeTag != null && !excludeTag.trim().isEmpty()) {
|
|
|
|
|
+ excludeTagsList.add(excludeTag.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ param.setOutTagsIdsSelectList(excludeTagsList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置筛选类型
|
|
|
|
|
+ param.setFilterType(wxSop.getFilterType());
|
|
|
|
|
+
|
|
|
|
|
+ return param;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询符合条件的客户
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param param 标签筛选参数
|
|
|
|
|
+ * @return 客户结果列表
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<WxFilterSopCustomersResult> selectFilterWxSopCustomers(WxSopTagsParam param) {
|
|
|
|
|
+ log.info("开始查询符合条件的客户...");
|
|
|
|
|
+ List<WxFilterSopCustomersResult> results = wxSopMapper.selectFilterWxSopCustomers(param);
|
|
|
|
|
+ log.info("客户查询完成,结果数: {}", results != null ? results.size() : 0);
|
|
|
|
|
+ return results;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 为客户创建营期记录
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param wxSop 个微SOP
|
|
|
|
|
+ * @param customerResults 客户结果列表
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public void createSopUserLogsWxForCustomers(WxSop wxSop, List<WxFilterSopCustomersResult> customerResults) {
|
|
|
|
|
+ log.info("====== 开始为 {} 个客户创建营期记录 ======", customerResults.size());
|
|
|
|
|
+ // 按执行账号分组创建营期
|
|
|
|
|
+ for (WxFilterSopCustomersResult customer : customerResults) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ log.info("处理客户: ID={}, 名称={}, 账号ID={}",
|
|
|
|
|
+ customer.getId(), customer.getName(), customer.getAccountId());
|
|
|
|
|
+ Long sopUserId = getOrCreateWxSopUser(wxSop, customer);
|
|
|
|
|
+
|
|
|
|
|
+ if (sopUserId == null) {
|
|
|
|
|
+ log.warn("创建营期失败,跳过客户:{}", customer.getId());
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("营期ID: {}", sopUserId);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 检查客户是否已在该营期中
|
|
|
|
|
+ WxSopUserInfo queryParam = new WxSopUserInfo();
|
|
|
|
|
+ queryParam.setSopId(wxSop.getId());
|
|
|
|
|
+ queryParam.setSopUserId(sopUserId);
|
|
|
|
|
+ queryParam.setWxContactId(Long.parseLong(customer.getId()));
|
|
|
|
|
+
|
|
|
|
|
+ WxSopUserInfo existingInfo = wxSopUserInfoMapper.selectWxSopUserInfoByCondition(queryParam);
|
|
|
|
|
+ if (existingInfo != null) {
|
|
|
|
|
+ log.info("客户已在营期中,跳过:客户ID={}, 营期ID={}", customer.getId(), sopUserId);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 创建营期成员记录(wx_sop_user_info)
|
|
|
|
|
+ WxSopUserInfo wxSopUserInfo = new WxSopUserInfo();
|
|
|
|
|
+ wxSopUserInfo.setSopId(wxSop.getId());
|
|
|
|
|
+ wxSopUserInfo.setSopUserId(sopUserId);
|
|
|
|
|
+ wxSopUserInfo.setWxContactId(Long.parseLong(customer.getId()));
|
|
|
|
|
+ if (customer.getCustomerId() != null && !customer.getCustomerId().isEmpty()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ wxSopUserInfo.setCustomerId(Long.parseLong(customer.getCustomerId()));
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ log.warn("客户ID格式错误:{}", customer.getCustomerId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置小程序ID(如果有)
|
|
|
|
|
+ if (customer.getFsUserId() != null && !customer.getFsUserId().isEmpty()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ wxSopUserInfo.setFsUserId(Long.parseLong(customer.getFsUserId()));
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ log.warn("小程序ID格式错误:{}", customer.getFsUserId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ wxSopUserInfo.setStatus(0); // 正常状态
|
|
|
|
|
+
|
|
|
|
|
+ int result = wxSopUserInfoMapper.insertWxSopUserInfo(wxSopUserInfo);
|
|
|
|
|
+ log.info("成功添加客户到营期:客户ID={}, 营期ID={}, SOP ID={}, 插入结果={}",
|
|
|
|
|
+ customer.getId(), sopUserId, wxSop.getId(), result);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("为客户创建营期记录失败,客户ID: {}", customer.getId(), e);
|
|
|
|
|
+ // 继续处理其他客户
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("====== 营期记录创建完成 ======");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取或创建营期主表记录
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param wxSop 个微SOP
|
|
|
|
|
+ * @param customer 客户信息
|
|
|
|
|
+ * @return 营期ID
|
|
|
|
|
+ */
|
|
|
|
|
+ private Long getOrCreateWxSopUser(WxSop wxSop, WxFilterSopCustomersResult customer) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 解析账号ID
|
|
|
|
|
+ Long accountId = null;
|
|
|
|
|
+ if (customer.getAccountId() != null && !customer.getAccountId().isEmpty()) {
|
|
|
|
|
+ accountId = Long.parseLong(customer.getAccountId());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.warn("客户账号ID为空,客户ID: {}", customer.getId());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 确定营期时间
|
|
|
|
|
+ LocalDate startTime;
|
|
|
|
|
+ if (wxSop.getIsFixed() != null && wxSop.getIsFixed() == 1) {
|
|
|
|
|
+ // 固定营期:使用SOP的开始时间
|
|
|
|
|
+ startTime = wxSop.getStartTime();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 非固定营期:使用今天
|
|
|
|
|
+ startTime = LocalDate.now();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询是否已存在营期
|
|
|
|
|
+ WxSopUser queryParam = new WxSopUser();
|
|
|
|
|
+ queryParam.setSopId(wxSop.getId());
|
|
|
|
|
+ queryParam.setType(0); // 个人类型
|
|
|
|
|
+ queryParam.setAccountId(accountId);
|
|
|
|
|
+ queryParam.setStartTime(startTime);
|
|
|
|
|
+
|
|
|
|
|
+ WxSopUser existingUser = wxSopUserMapper.selectwxSopUser(queryParam);
|
|
|
|
|
+ if (existingUser != null) {
|
|
|
|
|
+ return existingUser.getId();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建新的营期记录
|
|
|
|
|
+ WxSopUser wxSopUser = new WxSopUser();
|
|
|
|
|
+ wxSopUser.setType(0); // 个人类型
|
|
|
|
|
+ wxSopUser.setSopId(wxSop.getId());
|
|
|
|
|
+ wxSopUser.setAccountId(accountId);
|
|
|
|
|
+ wxSopUser.setStartTime(startTime);
|
|
|
|
|
+ wxSopUser.setStatus(0); // 正常状态
|
|
|
|
|
+
|
|
|
|
|
+ int result = wxSopUserMapper.insertWxSopUser(wxSopUser);
|
|
|
|
|
+ if (result > 0) {
|
|
|
|
|
+ log.info("创建营期成功:SOP ID={}, 账号ID={}, 营期时间={}, 营期ID={}",
|
|
|
|
|
+ wxSop.getId(), accountId, startTime, wxSopUser.getId());
|
|
|
|
|
+ return wxSopUser.getId();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("创建营期失败:SOP ID={}, 账号ID={}", wxSop.getId(), accountId);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("获取或创建营期失败", e);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 处理客户标签变更后的SOP营期动态管理
|
|
|
|
|
+ * 根据客户最新标签,自动加入或移出符合条件的营期
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param customerId 客户ID
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public void processCustomerTagsChange(Long customerId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ log.info("====== 开始处理客户标签变更,客户ID: {} ======", customerId);
|
|
|
|
|
+
|
|
|
|
|
+ CrmCustomer customer = crmCustomerMapper.selectCrmCustomerById(customerId);
|
|
|
|
|
+ if (customer == null) {
|
|
|
|
|
+ log.warn("客户不存在,客户ID: {}", customerId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("客户信息: ID={}, 名称={}, 标签={}", customerId, customer.getCustomerName(), customer.getTags());
|
|
|
|
|
+
|
|
|
|
|
+ WxSop sopQuery = new WxSop();
|
|
|
|
|
+ sopQuery.setStatus(2L);
|
|
|
|
|
+ sopQuery.setFilterType(0);
|
|
|
|
|
+ List<WxSop> enabledSops = wxSopMapper.selectWxSopList(sopQuery);
|
|
|
|
|
+ log.info("查询到 {} 个启用的标签筛选SOP", enabledSops != null ? enabledSops.size() : 0);
|
|
|
|
|
+
|
|
|
|
|
+ if (enabledSops == null || enabledSops.isEmpty()) {
|
|
|
|
|
+ log.info("没有启用的标签筛选SOP,无需处理");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (WxSop sop : enabledSops) {
|
|
|
|
|
+ processCustomerForSop(customer, sop);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("====== 客户标签变更处理完成,客户ID: {} ======", customerId);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理客户标签变更时发生异常,客户ID: {}", customerId, e);
|
|
|
|
|
+ throw e;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 处理单个客户在单个SOP中的营期管理
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param customer 客户信息
|
|
|
|
|
+ * @param sop SOP信息
|
|
|
|
|
+ */
|
|
|
|
|
+ public void processCustomerForSop(CrmCustomer customer, WxSop sop) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ log.info("检查客户是否符合SOP条件 - 客户ID: {}, SOP ID: {}, SOP名称: {}",
|
|
|
|
|
+ customer.getCustomerId(), sop.getId(), sop.getName());
|
|
|
|
|
+
|
|
|
|
|
+ boolean isMatch = checkCustomerMatchSopTags(customer, sop);
|
|
|
|
|
+ log.info("客户是否符合SOP条件: {}", isMatch);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ List<WxSopUserInfo> existingInfos = querySopUserInfosByCustomer(sop.getId(), customer.getCustomerId());
|
|
|
|
|
+
|
|
|
|
|
+ if (isMatch) {
|
|
|
|
|
+ // 符合条件:如果不在营期中,则加入
|
|
|
|
|
+ if (existingInfos == null || existingInfos.isEmpty()) {
|
|
|
|
|
+ log.info("客户符合条件且不在营期中,准备加入营期");
|
|
|
|
|
+ addCustomerToSop(customer, sop);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.info("客户已在营期中,无需重复加入");
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 不符合条件:如果在营期中,则移出
|
|
|
|
|
+ if (existingInfos != null && !existingInfos.isEmpty()) {
|
|
|
|
|
+ log.info("客户不符合条件但在营期中,准备移出营期,记录数: {}", existingInfos.size());
|
|
|
|
|
+ removeCustomerFromSop(customer, sop, existingInfos);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.info("客户不符合条件且不在营期中,无需处理");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理客户在SOP中的营期管理时发生异常,客户ID: {}, SOP ID: {}",
|
|
|
|
|
+ customer.getCustomerId(), sop.getId(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询客户在指定SOP下的所有营期成员记录
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param sopId SOP ID
|
|
|
|
|
+ * @param customerId 客户ID
|
|
|
|
|
+ * @return 营期成员记录列表
|
|
|
|
|
+ */
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public List<WxSopUserInfo> querySopUserInfosByCustomer(Long sopId, Long customerId) {
|
|
|
|
|
+ WxSopUserInfo queryParam = new WxSopUserInfo();
|
|
|
|
|
+ queryParam.setSopId(sopId);
|
|
|
|
|
+ queryParam.setCustomerId(customerId);
|
|
|
|
|
+ return wxSopUserInfoMapper.selectWxSopUserInfoList(queryParam);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查客户是否符合SOP的标签筛选条件
|
|
|
|
|
+ * 注意:客户tags字段与SOP的selectTags/excludeTags统一使用标签值(label)进行比对
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param customer 客户信息
|
|
|
|
|
+ * @param sop SOP信息
|
|
|
|
|
+ * @return true-符合条件,false-不符合条件
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean checkCustomerMatchSopTags(CrmCustomer customer, WxSop sop) {
|
|
|
|
|
+ String customerTags = customer.getTags();
|
|
|
|
|
+ if (customerTags == null || customerTags.trim().isEmpty()) {
|
|
|
|
|
+ log.info("客户标签为空");
|
|
|
|
|
+ // 如果客户没有标签,但SOP要求有筛选标签,则不符合
|
|
|
|
|
+ return sop.getSelectTags() == null || sop.getSelectTags().trim().isEmpty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 客户的标签列表(逗号分隔的标签值)- 需要将dict_label转换为dict_value
|
|
|
|
|
+ String[] customerTagArray = customerTags.split(",");
|
|
|
|
|
+ List<String> customerTagIdList = new ArrayList<>();
|
|
|
|
|
+ for (String tagLabel : customerTagArray) {
|
|
|
|
|
+ if (tagLabel != null && !tagLabel.trim().isEmpty()) {
|
|
|
|
|
+ // 将标签名(dict_label)转换为标签ID(dict_value)
|
|
|
|
|
+ String tagId = com.fs.common.utils.DictUtils.getDictValue("crm_customer_tag", tagLabel.trim());
|
|
|
|
|
+ if (tagId != null && !tagId.isEmpty()) {
|
|
|
|
|
+ customerTagIdList.add(tagId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("客户标签ID列表: {}", customerTagIdList);
|
|
|
|
|
+
|
|
|
|
|
+ // 检查必须包含的标签(selectTags)- 直接使用标签ID比对
|
|
|
|
|
+ if (sop.getSelectTags() != null && !sop.getSelectTags().trim().isEmpty()) {
|
|
|
|
|
+ String[] selectTags = sop.getSelectTags().split(",");
|
|
|
|
|
+ for (String tag : selectTags) {
|
|
|
|
|
+ if (tag != null && !tag.trim().isEmpty()) {
|
|
|
|
|
+ String trimmedTag = tag.trim();
|
|
|
|
|
+ if (!customerTagIdList.contains(trimmedTag)) {
|
|
|
|
|
+ log.info("客户缺少必需标签ID: {}", trimmedTag);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("客户包含所有必需标签");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查排除的标签(excludeTags)- 直接使用标签ID比对
|
|
|
|
|
+ if (sop.getExcludeTags() != null && !sop.getExcludeTags().trim().isEmpty()) {
|
|
|
|
|
+ String[] excludeTags = sop.getExcludeTags().split(",");
|
|
|
|
|
+ for (String tag : excludeTags) {
|
|
|
|
|
+ if (tag != null && !tag.trim().isEmpty()) {
|
|
|
|
|
+ String trimmedTag = tag.trim();
|
|
|
|
|
+ if (customerTagIdList.contains(trimmedTag)) {
|
|
|
|
|
+ log.info("客户包含排除标签ID: {}", trimmedTag);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("客户不包含排除标签");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("客户符合SOP标签筛选条件");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将客户加入SOP营期
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param customer 客户信息
|
|
|
|
|
+ * @param sop SOP信息
|
|
|
|
|
+ */
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public void addCustomerToSop(CrmCustomer customer, WxSop sop) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ WxFilterSopCustomersResult customerResult = new WxFilterSopCustomersResult();
|
|
|
|
|
+ customerResult.setId(customer.getCustomerId().toString());
|
|
|
|
|
+ customerResult.setName(customer.getCustomerName());
|
|
|
|
|
+ if (sop.getAccountIds() != null && !sop.getAccountIds().isEmpty()) {
|
|
|
|
|
+ String[] accountIds = sop.getAccountIds().split(",");
|
|
|
|
|
+ if (accountIds.length > 0) {
|
|
|
|
|
+ customerResult.setAccountId(accountIds[0].trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (customerResult.getAccountId() == null) {
|
|
|
|
|
+ log.warn("无法获取执行账号,跳过加入营期");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取或创建营期
|
|
|
|
|
+ Long sopUserId = getOrCreateWxSopUser(sop, customerResult);
|
|
|
|
|
+ if (sopUserId == null) {
|
|
|
|
|
+ log.warn("创建营期失败,跳过");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建营期成员记录
|
|
|
|
|
+ WxSopUserInfo wxSopUserInfo = new WxSopUserInfo();
|
|
|
|
|
+ wxSopUserInfo.setSopId(sop.getId());
|
|
|
|
|
+ wxSopUserInfo.setSopUserId(sopUserId);
|
|
|
|
|
+ wxSopUserInfo.setCustomerId(customer.getCustomerId());
|
|
|
|
|
+ wxSopUserInfo.setStatus(0); // 正常状态
|
|
|
|
|
+ wxSopUserInfo.setTagNames(customer.getTags());
|
|
|
|
|
+
|
|
|
|
|
+ int result = wxSopUserInfoMapper.insertWxSopUserInfo(wxSopUserInfo);
|
|
|
|
|
+ log.info("成功将客户加入营期:客户ID={}, 营期ID={}, SOP ID={}, 插入结果={}",
|
|
|
|
|
+ customer.getCustomerId(), sopUserId, sop.getId(), result);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("将客户加入SOP营期时发生异常", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将客户从SOP营期中移出
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param customer 客户信息
|
|
|
|
|
+ * @param sop SOP信息
|
|
|
|
|
+ * @param existingInfos 已存在的营期成员记录
|
|
|
|
|
+ */
|
|
|
|
|
+ @DataSource(DataSourceType.SOP)
|
|
|
|
|
+ public void removeCustomerFromSop(CrmCustomer customer, WxSop sop, List<WxSopUserInfo> existingInfos) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ for (WxSopUserInfo info : existingInfos) {
|
|
|
|
|
+ int result = wxSopUserInfoMapper.deleteWxSopUserInfoById(info.getId());
|
|
|
|
|
+ log.info("成功将客户从营期中移出:客户ID={}, 营期成员记录ID={}, SOP ID={}, 删除结果={}",
|
|
|
|
|
+ customer.getCustomerId(), info.getId(), sop.getId(), result);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("将客户从SOP营期中移出时发生异常", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|