|
|
@@ -39,6 +39,7 @@ import com.fs.crm.service.impl.CrmCustomerServiceImpl;
|
|
|
import com.fs.enums.ExecutionStatusEnum;
|
|
|
import com.fs.enums.NodeTypeEnum;
|
|
|
import com.fs.enums.TaskTypeEnum;
|
|
|
+import com.fs.his.utils.PhoneUtil;
|
|
|
import com.fs.qw.domain.QwUser;
|
|
|
import com.fs.qw.mapper.QwUserMapper;
|
|
|
import com.fs.qw.service.impl.QwExternalContactServiceImpl;
|
|
|
@@ -1764,11 +1765,14 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
|
|
|
Integer pageSize,
|
|
|
String customerName,
|
|
|
String customerPhone,
|
|
|
- Boolean onlyCallNode) {
|
|
|
+ Boolean onlyCallNode,
|
|
|
+ String encryptPhone) {
|
|
|
//分页查询主数据
|
|
|
PageHelper.startPage(pageNum, pageSize);
|
|
|
-
|
|
|
- List<WorkflowExecRecordVo> records = companyAiWorkflowExecMapper.selectExecRecordsByRoboticId(roboticId, customerName, customerPhone, onlyCallNode);
|
|
|
+ if(StringUtils.isNotBlank(encryptPhone)){
|
|
|
+ encryptPhone = PhoneUtil.encryptPhone(encryptPhone);
|
|
|
+ }
|
|
|
+ List<WorkflowExecRecordVo> records = companyAiWorkflowExecMapper.selectExecRecordsByRoboticId(roboticId, customerName, customerPhone, onlyCallNode,encryptPhone);
|
|
|
|
|
|
PageInfo<WorkflowExecRecordVo> pageInfo = new PageInfo<>(records);
|
|
|
|
|
|
@@ -1909,7 +1913,7 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
List<CompanyAiWorkflowExecLog> callLogs = logs.stream().filter(a -> "外呼".equals(a.getNodeName())).collect(Collectors.toList());
|
|
|
- HashMap<Long,String> callContentMap;
|
|
|
+ HashMap<Long,CallContentVO> callContentMap;
|
|
|
if (null != callLogs && !callLogs.isEmpty()) {
|
|
|
callContentMap = selectCallContentByCallLogs(callLogs);
|
|
|
} else {
|
|
|
@@ -1929,7 +1933,11 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
|
|
|
vo.setDuration(log.getDuration());
|
|
|
vo.setErrorMessage(log.getErrorMessage());
|
|
|
vo.setOutputData(log.getOutputData());
|
|
|
- vo.setNodeContentList(callContentMap.get(log.getId()));
|
|
|
+ CallContentVO callContentVO = callContentMap.get(log.getId());
|
|
|
+ if (callContentVO != null) {
|
|
|
+ vo.setNodeContentList(callContentVO.getCallContent());
|
|
|
+ vo.setNodeRecordPath(callContentVO.getRecordPath());
|
|
|
+ }
|
|
|
return vo;
|
|
|
}).collect(Collectors.toList());
|
|
|
}
|
|
|
@@ -1939,15 +1947,15 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
|
|
|
* @param callLogs
|
|
|
* @return
|
|
|
*/
|
|
|
- public HashMap<Long,String> selectCallContentByCallLogs(List<CompanyAiWorkflowExecLog> callLogs){
|
|
|
+ public HashMap<Long,CallContentVO> selectCallContentByCallLogs(List<CompanyAiWorkflowExecLog> callLogs){
|
|
|
List<Long> ids = callLogs.stream().map(a -> a.getId()).collect(Collectors.toList());
|
|
|
if(null == ids || ids.isEmpty()){
|
|
|
return new HashMap<>();
|
|
|
}
|
|
|
List<CallContentVO> callContentVOS = companyAiWorkflowExecLogMapper.selectCallContent(ids);
|
|
|
if(null != callContentVOS && !callContentVOS.isEmpty()){
|
|
|
- HashMap<Long,String> map = new HashMap<>();
|
|
|
- callContentVOS.forEach(a -> map.put(a.getLogId(),a.getCallContent()));
|
|
|
+ HashMap<Long,CallContentVO> map = new HashMap<>();
|
|
|
+ callContentVOS.forEach(a -> map.put(a.getLogId(), a));
|
|
|
return map;
|
|
|
}
|
|
|
else{
|
|
|
@@ -2228,4 +2236,179 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R appendCustomersToRunningTask(Long taskId, List<Long> customerIds) {
|
|
|
+ // 1. 校验参数
|
|
|
+ if (taskId == null || customerIds == null || customerIds.isEmpty()) {
|
|
|
+ return R.error("参数不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 校验任务
|
|
|
+ CompanyVoiceRobotic robotic = companyVoiceRoboticMapper.selectCompanyVoiceRoboticById(taskId);
|
|
|
+ if (robotic == null) {
|
|
|
+ return R.error("任务不存在: " + taskId);
|
|
|
+ }
|
|
|
+ if (!robotic.getTaskType().equals(TaskTypeEnum.ORDINARY.getValue())) {
|
|
|
+ return R.error("仅普通任务支持追加客户");
|
|
|
+ }
|
|
|
+ if (!Integer.valueOf(1).equals(robotic.getTaskStatus())) {
|
|
|
+ return R.error("任务不在执行中状态,无法追加客户");
|
|
|
+ }
|
|
|
+ if (robotic.getCompanyAiWorkflowId() == null) {
|
|
|
+ return R.error("任务未配置工作流");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 查询当前任务已有的callees的userId集合,过滤重复
|
|
|
+ List<CompanyVoiceRoboticCallees> existingCallees = companyVoiceRoboticCalleesMapper.selectByRoboticId(taskId);
|
|
|
+ Set<Long> existingUserIds = existingCallees.stream()
|
|
|
+ .map(CompanyVoiceRoboticCallees::getUserId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 分离重复和非重复客户
|
|
|
+ List<Long> duplicateIds = customerIds.stream()
|
|
|
+ .filter(existingUserIds::contains)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ List<Long> newCustomerIds = customerIds.stream()
|
|
|
+ .filter(id -> !existingUserIds.contains(id))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (newCustomerIds.isEmpty()) {
|
|
|
+ String dupNames = getDuplicateCustomerNames(duplicateIds);
|
|
|
+ return R.error("所选客户已存在于任务中" + (dupNames.isEmpty() ? "" : ":" + dupNames));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 批量查询CRM客户信息
|
|
|
+ List<CrmCustomer> crmCustomers = crmCustomerService.selectCrmCustomerListByIds(
|
|
|
+ newCustomerIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
|
|
+ Map<Long, CrmCustomer> customerMap = crmCustomers.stream()
|
|
|
+ .collect(Collectors.toMap(CrmCustomer::getCustomerId, c -> c, (a, b) -> a));
|
|
|
+
|
|
|
+ // 5. 判断是否需要加微分配
|
|
|
+ boolean hasAddWxNode = workflowHasAddWxNode(robotic.getCompanyAiWorkflowId());
|
|
|
+
|
|
|
+ int successCount = 0;
|
|
|
+ List<String> errorMessages = new ArrayList<>();
|
|
|
+
|
|
|
+ for (Long customerId : newCustomerIds) {
|
|
|
+ CrmCustomer crmCustomer = customerMap.get(customerId);
|
|
|
+ if (crmCustomer == null) {
|
|
|
+ errorMessages.add("客户不存在: " + customerId);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 5.1 创建CompanyWxClient记录
|
|
|
+ CompanyWxClient client = new CompanyWxClient();
|
|
|
+ client.setRoboticId(taskId);
|
|
|
+ client.setCustomerId(customerId);
|
|
|
+ client.setIsWeCom(robotic.getIsWeCom());
|
|
|
+ companyWxClientServiceImpl.insertCompanyWxClient(client);
|
|
|
+
|
|
|
+ // 5.2 创建CompanyVoiceRoboticCallees记录
|
|
|
+ CompanyVoiceRoboticCallees callee = new CompanyVoiceRoboticCallees();
|
|
|
+ callee.setUserId(crmCustomer.getCustomerId());
|
|
|
+ callee.setUserName(crmCustomer.getCustomerName());
|
|
|
+ callee.setPhone(crmCustomer.getMobile());
|
|
|
+ callee.setRoboticId(robotic.getId());
|
|
|
+ callee.setResult(0);
|
|
|
+ callee.setTaskFlow(robotic.getTaskFlow());
|
|
|
+ callee.setRunTaskFlow(robotic.getRunTaskFlow());
|
|
|
+ callee.setIsWeCom(robotic.getIsWeCom());
|
|
|
+ companyVoiceRoboticCalleesService.save(callee);
|
|
|
+
|
|
|
+ // 5.3 加微分配
|
|
|
+ if (hasAddWxNode && Integer.valueOf(0).equals(robotic.getAddType())) {
|
|
|
+ allocateWx4SceneTask(robotic, client.getId());
|
|
|
+ } else if (hasAddWxNode && Integer.valueOf(1).equals(robotic.getAddType())) {
|
|
|
+ String intention = crmCustomer.getIntention();
|
|
|
+ String queryIntention = intention;
|
|
|
+ if (!isPositiveInteger(intention)) {
|
|
|
+ List<SysDictData> customerIntentionLevel = sysDictTypeService.selectDictDataByType("customer_intention_level");
|
|
|
+ Optional<SysDictData> firstDict = customerIntentionLevel.stream()
|
|
|
+ .filter(e -> e.getDictLabel().equals(intention)).findFirst();
|
|
|
+ if (firstDict.isPresent()) {
|
|
|
+ queryIntention = firstDict.get().getDictValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<CompanyVoiceRoboticWx> roboticWxList = companyVoiceRoboticWxMapper.selectByRoboticId(taskId, queryIntention);
|
|
|
+ List<CompanyWxAccount> accountList = new ArrayList<>(companyWxAccountService.listByIds(PubFun.listToNewList(roboticWxList, CompanyVoiceRoboticWx::getAccountId)));
|
|
|
+ Map<Long, CompanyWxAccount> accountMap = PubFun.listToMapByGroupObject(accountList, CompanyWxAccount::getId);
|
|
|
+ roboticWxList.forEach(e -> e.setAccount(accountMap.get(e.getAccountId())));
|
|
|
+ CompanyWxClient companyWxClient = companyWxClientServiceImpl.getOne(new QueryWrapper<CompanyWxClient>().eq("robotic_id", callee.getRoboticId()).eq("customer_id", callee.getUserId()));
|
|
|
+ if (companyWxClient == null) {
|
|
|
+ companyWxClient = new CompanyWxClient();
|
|
|
+ }
|
|
|
+ companyWxClient.setRoboticId(callee.getRoboticId());
|
|
|
+ companyWxClient.setNickName(callee.getUserName());
|
|
|
+ companyWxClient.setPhone(callee.getPhone());
|
|
|
+ companyWxClient.setCustomerId(callee.getUserId());
|
|
|
+ companyWxClient.setIntention(intention);
|
|
|
+ bindCompany(companyWxClient, roboticWxList);
|
|
|
+ companyWxClientServiceImpl.saveOrUpdate(companyWxClient);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5.4 创建CompanyVoiceRoboticBusiness记录
|
|
|
+ CompanyVoiceRoboticBusiness business = buildTaskBussiness4SceneTask(robotic, callee);
|
|
|
+
|
|
|
+ // 5.5 初始化工作流实例
|
|
|
+ Map<String, Object> inputVariables = new HashMap<>();
|
|
|
+ inputVariables.put("roboticId", robotic.getId());
|
|
|
+ inputVariables.put("businessId", business.getId());
|
|
|
+ inputVariables.put("cidGroupNo", robotic.getCidGroupNo());
|
|
|
+ inputVariables.put("runtimeRangeStart", robotic.getRuntimeRangeStart());
|
|
|
+ inputVariables.put("runtimeRangeEnd", robotic.getRuntimeRangeEnd());
|
|
|
+ ExecutionResult initResult = companyWorkflowEngine.initialize(robotic.getCompanyAiWorkflowId(), inputVariables);
|
|
|
+ if (!initResult.isSuccess()) {
|
|
|
+ errorMessages.add("客户" + crmCustomer.getCustomerName() + "工作流初始化失败: " + initResult.getErrorMessage());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ successCount++;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("追加客户失败 - taskId: {}, customerId: {}", taskId, customerId, e);
|
|
|
+ errorMessages.add("客户" + crmCustomer.getCustomerName() + "追加失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 为新增的callees生成AI标签信息
|
|
|
+ if (successCount > 0) {
|
|
|
+ try {
|
|
|
+ List<CompanyVoiceRoboticCallees> allCallees = companyVoiceRoboticCalleesMapper.selectByRoboticId(taskId);
|
|
|
+ List<CompanyWxClient> companyWxClients = companyWxClientMapper.selectListByRoboticId(taskId);
|
|
|
+ Map<String, CompanyWxClient> clientMp = companyWxClients.stream()
|
|
|
+ .collect(Collectors.toMap(e -> e.getRoboticId() + "-" + e.getCustomerId(), e -> e, (a, b) -> a));
|
|
|
+ asyncCalleeProcessorService.generateCustomerInfo(allCallees, clientMp, robotic);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("追加客户后生成AI标签信息异常 - taskId: {}", taskId, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 构建返回结果
|
|
|
+ Map<String, Object> resultData = new HashMap<>();
|
|
|
+ resultData.put("successCount", successCount);
|
|
|
+ if (!duplicateIds.isEmpty()) {
|
|
|
+ resultData.put("duplicateCustomerNames", getDuplicateCustomerNames(duplicateIds));
|
|
|
+ }
|
|
|
+ if (!errorMessages.isEmpty()) {
|
|
|
+ resultData.put("errorMessages", errorMessages);
|
|
|
+ }
|
|
|
+ return R.ok(resultData);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据客户ID列表获取重复客户名称
|
|
|
+ */
|
|
|
+ private String getDuplicateCustomerNames(List<Long> customerIds) {
|
|
|
+ if (customerIds == null || customerIds.isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ List<CrmCustomer> customers = crmCustomerService.selectCrmCustomerListByIds(
|
|
|
+ customerIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
|
|
+ return customers.stream().map(CrmCustomer::getCustomerName).filter(Objects::nonNull).collect(Collectors.joining("、"));
|
|
|
+ } catch (Exception e) {
|
|
|
+ return customerIds.stream().map(String::valueOf).collect(Collectors.joining("、"));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|