|
|
@@ -0,0 +1,473 @@
|
|
|
+package com.fs.company.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
+import com.fs.company.domain.*;
|
|
|
+import com.fs.company.mapper.*;
|
|
|
+import com.fs.company.service.IAsyncCalleeProcessorService;
|
|
|
+import com.fs.company.util.RandomNameGeneratorUtil;
|
|
|
+import com.fs.company.vo.CompanyNodeInfoVo;
|
|
|
+import com.fs.enums.ExecutionStatusEnum;
|
|
|
+import com.fs.enums.NodeTypeEnum;
|
|
|
+import com.fs.his.config.CidPhoneConfig;
|
|
|
+import com.fs.system.service.ISysConfigService;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ThreadLocalRandom;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class AsyncCalleeProcessorServiceImpl implements IAsyncCalleeProcessorService {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(AsyncCalleeProcessorServiceImpl.class);
|
|
|
+
|
|
|
+ private static final int BATCH_SIZE = 1500;
|
|
|
+ private static final int CPU_YIELD_INTERVAL = 500;
|
|
|
+ private static final int SLEEP_INTERVAL = 2000;
|
|
|
+ private static final int SLEEP_MILLIS = 10;
|
|
|
+ private static final int PHONE_LENGTH = 11;
|
|
|
+ private static final char DIGIT_ZERO = '0';
|
|
|
+ private static final int RADIX_TEN = 10;
|
|
|
+
|
|
|
+ private final ISysConfigService configService;
|
|
|
+ private final CompanyWorkflowEdgeMapper edgeMapper;
|
|
|
+ private final CompanyConfigMapper companyConfigMapper;
|
|
|
+ private final CompanyWorkflowMapper companyWorkflowMapper;
|
|
|
+ private final CompanyAiWorkflowExecMapper companyAiWorkflowExecMapper;
|
|
|
+ private final CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
|
|
|
+ private final CompanyVoiceRoboticBusinessMapper companyVoiceRoboticBusinessMapper;
|
|
|
+ private final CompanyVoiceRoboticCalleesMapper companyVoiceRoboticCalleesMapper;
|
|
|
+
|
|
|
+ AsyncCalleeProcessorServiceImpl(CompanyConfigMapper companyConfigMapper,
|
|
|
+ ISysConfigService configService,
|
|
|
+ CompanyWorkflowEdgeMapper edgeMapper,
|
|
|
+ CompanyWorkflowMapper companyWorkflowMapper,
|
|
|
+ CompanyAiWorkflowExecMapper companyAiWorkflowExecMapper,
|
|
|
+ CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper,
|
|
|
+ CompanyVoiceRoboticBusinessMapper companyVoiceRoboticBusinessMapper,
|
|
|
+ CompanyVoiceRoboticCalleesMapper companyVoiceRoboticCalleesMapper) {
|
|
|
+ this.companyConfigMapper = companyConfigMapper;
|
|
|
+ this.configService = configService;
|
|
|
+ this.edgeMapper = edgeMapper;
|
|
|
+ this.companyWorkflowMapper = companyWorkflowMapper;
|
|
|
+ this.companyAiWorkflowExecMapper = companyAiWorkflowExecMapper;
|
|
|
+ this.companyAiWorkflowExecLogMapper = companyAiWorkflowExecLogMapper;
|
|
|
+ this.companyVoiceRoboticBusinessMapper = companyVoiceRoboticBusinessMapper;
|
|
|
+ this.companyVoiceRoboticCalleesMapper = companyVoiceRoboticCalleesMapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Async("calleeTaskExecutor")
|
|
|
+ public void generateCustomerInfo(List<CompanyVoiceRoboticCallees> calleesList,
|
|
|
+ Map<String, CompanyWxClient> clientMp,
|
|
|
+ CompanyVoiceRobotic robotic) {
|
|
|
+ if (calleesList == null || calleesList.isEmpty() || robotic == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Thread currentThread = Thread.currentThread();
|
|
|
+ if (currentThread.isInterrupted()) {
|
|
|
+ log.info("任务被中断,退出处理");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ CidPhoneConfig phoneConfig = loadPhoneConfig(robotic.getCompanyId());
|
|
|
+ if (phoneConfig == null || !Boolean.TRUE.equals(phoneConfig.getEnablePhoneConfig())) {
|
|
|
+ log.warn("电话配置未启用或为空,companyId: {}", robotic.getCompanyId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyWorkflow workflow = loadWorkflow(robotic.getCompanyAiWorkflowId());
|
|
|
+ if (workflow == null) {
|
|
|
+ log.warn("工作流不存在,workflowId: {}", robotic.getCompanyAiWorkflowId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyNodeInfoVo nodeInfoVo = loadNodeInfo(workflow.getWorkflowId(), workflow.getStartNodeKey());
|
|
|
+ if (nodeInfoVo == null) {
|
|
|
+ log.warn("节点信息不存在,workflowId: {}, startNodeKey: {}", workflow.getWorkflowId(), workflow.getStartNodeKey());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CompanyVoiceRoboticCallees> batchToInsert = new ArrayList<>(BATCH_SIZE);
|
|
|
+ int processedCount = 0;
|
|
|
+
|
|
|
+ for (CompanyVoiceRoboticCallees callees : calleesList) {
|
|
|
+ if (currentThread.isInterrupted()) {
|
|
|
+ log.info("任务被中断,已处理 {} 条", processedCount);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ generatePhoneNumberInBatch(phoneConfig, callees, batchToInsert, clientMp, robotic, workflow, nodeInfoVo);
|
|
|
+ processedCount++;
|
|
|
+
|
|
|
+ if (processedCount % CPU_YIELD_INTERVAL == 0) {
|
|
|
+ Thread.yield();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (processedCount % SLEEP_INTERVAL == 0) {
|
|
|
+ Thread.sleep(SLEEP_MILLIS);
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ log.info("任务被中断,已处理 {} 条", processedCount);
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ break;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理被叫信息异常,phone: {}", callees.getPhone(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("generateCustomerInfo处理完成,共处理 {} 条", processedCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ private CidPhoneConfig loadPhoneConfig(Long companyId) {
|
|
|
+ try {
|
|
|
+ CompanyConfig companyConfig = companyConfigMapper.selectCompanyConfigByKey(companyId, "cid.config");
|
|
|
+ if (companyConfig != null && StringUtils.isNotEmpty(companyConfig.getConfigValue())) {
|
|
|
+ return JSONObject.parseObject(companyConfig.getConfigValue(), CidPhoneConfig.class);
|
|
|
+ }
|
|
|
+ String json = configService.selectConfigByKey("his.store");
|
|
|
+ if (StringUtils.isNotEmpty(json)) {
|
|
|
+ return JSONObject.parseObject(json, CidPhoneConfig.class);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载电话配置异常,companyId: {}", companyId, e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyWorkflow loadWorkflow(Long workflowId) {
|
|
|
+ try {
|
|
|
+ return companyWorkflowMapper.selectCompanyWorkflowById(workflowId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载工作流异常,workflowId: {}", workflowId, e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyNodeInfoVo loadNodeInfo(Long workflowId, String startNodeKey) {
|
|
|
+ try {
|
|
|
+ return edgeMapper.slectNodeInfoByWorkflowId(workflowId, startNodeKey);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载节点信息异常,workflowId: {}, startNodeKey: {}", workflowId, startNodeKey, e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void generatePhoneNumberInBatch(CidPhoneConfig config,
|
|
|
+ CompanyVoiceRoboticCallees callees,
|
|
|
+ List<CompanyVoiceRoboticCallees> batchToInsert,
|
|
|
+ Map<String, CompanyWxClient> clientMp,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo) {
|
|
|
+ String basePhone = callees.getPhone();
|
|
|
+ if (basePhone == null || basePhone.length() != PHONE_LENGTH) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int start = config.getStartIndex();
|
|
|
+ int end = config.getEndIndex();
|
|
|
+ int totalCount = config.getGenerateCount();
|
|
|
+
|
|
|
+ if (!isValidRange(start, end)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int startIdx = start - 1;
|
|
|
+ int endIdx = end - 1;
|
|
|
+ char[] baseChars = basePhone.toCharArray();
|
|
|
+ ThreadLocalRandom random = ThreadLocalRandom.current();
|
|
|
+ int nameIndex = 0;
|
|
|
+
|
|
|
+ while (nameIndex < totalCount) {
|
|
|
+ if (Thread.currentThread().isInterrupted()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ int currentBatchSize = Math.min(BATCH_SIZE, totalCount - nameIndex);
|
|
|
+
|
|
|
+ for (int i = 0; i < currentBatchSize; i++) {
|
|
|
+ CompanyVoiceRoboticCallees roboticCallees = createCalleesWithPhone(
|
|
|
+ baseChars, startIdx, endIdx, random, callees);
|
|
|
+ batchToInsert.add(roboticCallees);
|
|
|
+ }
|
|
|
+
|
|
|
+ nameIndex += currentBatchSize;
|
|
|
+
|
|
|
+ if (batchToInsert.size() >= BATCH_SIZE || nameIndex >= totalCount) {
|
|
|
+ flushGeneratedCalleesBatch(batchToInsert, clientMp, robotic, workflow, nodeInfoVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nameIndex % SLEEP_INTERVAL == 0) {
|
|
|
+ try {
|
|
|
+ Thread.sleep(SLEEP_MILLIS);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isValidRange(int start, int end) {
|
|
|
+ return start >= 1 && start <= PHONE_LENGTH
|
|
|
+ && end >= 1 && end <= PHONE_LENGTH
|
|
|
+ && start <= end;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyVoiceRoboticCallees createCalleesWithPhone(char[] baseChars, int startIdx, int endIdx,
|
|
|
+ ThreadLocalRandom random,
|
|
|
+ CompanyVoiceRoboticCallees template) {
|
|
|
+ char[] newChars = baseChars.clone();
|
|
|
+ for (int j = startIdx; j <= endIdx; j++) {
|
|
|
+ newChars[j] = (char) (DIGIT_ZERO + random.nextInt(RADIX_TEN));
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyVoiceRoboticCallees roboticCallees = new CompanyVoiceRoboticCallees();
|
|
|
+ roboticCallees.setPhone(new String(newChars));
|
|
|
+ roboticCallees.setRoboticId(template.getRoboticId());
|
|
|
+ roboticCallees.setTaskFlow(template.getTaskFlow());
|
|
|
+ roboticCallees.setRunTaskFlow(template.getRunTaskFlow());
|
|
|
+ roboticCallees.setIsWeCom(template.getIsWeCom());
|
|
|
+ roboticCallees.setUserId(0L);
|
|
|
+ roboticCallees.setUserName(RandomNameGeneratorUtil.generateOne());
|
|
|
+ roboticCallees.setIsGenerate(1);
|
|
|
+
|
|
|
+ return roboticCallees;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void flushGeneratedCalleesBatch(List<CompanyVoiceRoboticCallees> batchToInsert,
|
|
|
+ Map<String, CompanyWxClient> clientMap,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo) {
|
|
|
+ if (batchToInsert == null || batchToInsert.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ int rows = companyVoiceRoboticCalleesMapper.batchInsertGenerateInfo(batchToInsert);
|
|
|
+ if (rows > 0) {
|
|
|
+ generateVoiceRoboticBusiness(batchToInsert, clientMap, robotic, workflow, nodeInfoVo);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量插入被叫数据异常,size: {}", batchToInsert.size(), e);
|
|
|
+ } finally {
|
|
|
+ batchToInsert.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void generateVoiceRoboticBusiness(List<CompanyVoiceRoboticCallees> calleesList,
|
|
|
+ Map<String, CompanyWxClient> clientMp,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo) {
|
|
|
+ if (calleesList == null || calleesList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CompanyVoiceRoboticBusiness> addList = new ArrayList<>(calleesList.size());
|
|
|
+ Date date = new Date();
|
|
|
+
|
|
|
+ for (CompanyVoiceRoboticCallees callees : calleesList) {
|
|
|
+ CompanyVoiceRoboticBusiness business = createBusiness(callees, clientMp, date);
|
|
|
+ addList.add(business);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!addList.isEmpty()) {
|
|
|
+ flushGeneratedBusinessBatch(addList, robotic, workflow, nodeInfoVo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyVoiceRoboticBusiness createBusiness(CompanyVoiceRoboticCallees callees,
|
|
|
+ Map<String, CompanyWxClient> clientMp,
|
|
|
+ Date date) {
|
|
|
+ CompanyVoiceRoboticBusiness business = new CompanyVoiceRoboticBusiness();
|
|
|
+ business.setRoboticId(callees.getRoboticId());
|
|
|
+ business.setCalleeId(callees.getId());
|
|
|
+
|
|
|
+ String clientKey = callees.getRoboticId() + "-" + callees.getUserId();
|
|
|
+ CompanyWxClient client = clientMp.get(clientKey);
|
|
|
+ business.setWxClientId(client != null ? client.getId() : null);
|
|
|
+
|
|
|
+ business.setAddWxDone(0);
|
|
|
+ business.setCallPhoneDone(0);
|
|
|
+ business.setSendMsgDone(0);
|
|
|
+ business.setCreateTime(date);
|
|
|
+ business.setIsGenerate(1);
|
|
|
+
|
|
|
+ return business;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void flushGeneratedBusinessBatch(List<CompanyVoiceRoboticBusiness> batchToInsert,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo) {
|
|
|
+ if (batchToInsert == null || batchToInsert.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ int rows = companyVoiceRoboticBusinessMapper.insertBatchGenerateInfo(batchToInsert);
|
|
|
+ if (rows > 0) {
|
|
|
+ generateWorkflowExecRecords(batchToInsert, robotic, workflow, nodeInfoVo);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量插入业务数据异常,size: {}", batchToInsert.size(), e);
|
|
|
+ } finally {
|
|
|
+ batchToInsert.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void generateWorkflowExecRecords(List<CompanyVoiceRoboticBusiness> businessList,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo) {
|
|
|
+ if (businessList == null || businessList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ List<CompanyAiWorkflowExec> startExecList = new ArrayList<>(businessList.size());
|
|
|
+ List<CompanyAiWorkflowExec> targetExecList = new ArrayList<>(businessList.size());
|
|
|
+
|
|
|
+ for (CompanyVoiceRoboticBusiness business : businessList) {
|
|
|
+ if (Thread.currentThread().isInterrupted()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyAiWorkflowExec startExec = createStartExec(business, robotic, workflow, now);
|
|
|
+ startExecList.add(startExec);
|
|
|
+
|
|
|
+ CompanyAiWorkflowExec targetExec = createTargetExec(startExec, nodeInfoVo, now);
|
|
|
+ targetExecList.add(targetExec);
|
|
|
+
|
|
|
+ if (targetExecList.size() >= BATCH_SIZE) {
|
|
|
+ persistExecLogs(targetExecList, startExecList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!targetExecList.isEmpty()) {
|
|
|
+ persistExecLogs(targetExecList, startExecList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyAiWorkflowExec createStartExec(CompanyVoiceRoboticBusiness business,
|
|
|
+ CompanyVoiceRobotic robotic,
|
|
|
+ CompanyWorkflow workflow,
|
|
|
+ LocalDateTime now) {
|
|
|
+ CompanyAiWorkflowExec exec = new CompanyAiWorkflowExec();
|
|
|
+ exec.setWorkflowInstanceId(generateInstanceId());
|
|
|
+ exec.setWorkflowId(robotic.getCompanyAiWorkflowId());
|
|
|
+ exec.setCurrentNodeKey(workflow.getStartNodeKey());
|
|
|
+ exec.setCurrentNodeType(NodeTypeEnum.START.getValue());
|
|
|
+ exec.setCurrentNodeName(NodeTypeEnum.START.getDescription());
|
|
|
+ exec.setStatus(ExecutionStatusEnum.SUCCESS.getValue());
|
|
|
+ exec.setStartTime(now);
|
|
|
+ exec.setVariables(buildVariables(robotic, business));
|
|
|
+ exec.setBusinessKey(business.getId());
|
|
|
+ exec.setStartNodeKey(workflow.getStartNodeKey());
|
|
|
+ exec.setEndNodeKey(workflow.getEndNodeKey());
|
|
|
+ exec.setCidGroupNo(robotic.getCidGroupNo());
|
|
|
+ exec.setRuntimeRangeStart(robotic.getRuntimeRangeStart());
|
|
|
+ exec.setRuntimeRangeEnd(robotic.getRuntimeRangeEnd());
|
|
|
+ exec.setIsGenerate(1);
|
|
|
+ return exec;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyAiWorkflowExec createTargetExec(CompanyAiWorkflowExec startExec,
|
|
|
+ CompanyNodeInfoVo nodeInfoVo,
|
|
|
+ LocalDateTime now) {
|
|
|
+ CompanyAiWorkflowExec exec = new CompanyAiWorkflowExec();
|
|
|
+ exec.setWorkflowInstanceId(startExec.getWorkflowInstanceId());
|
|
|
+ exec.setWorkflowId(startExec.getWorkflowId());
|
|
|
+ exec.setCurrentNodeKey(nodeInfoVo.getTargetNodeKey());
|
|
|
+ exec.setCurrentNodeName(nodeInfoVo.getNodeName());
|
|
|
+ exec.setCurrentNodeType(NodeTypeEnum.fromCode(nodeInfoVo.getNodeType()).getValue());
|
|
|
+ exec.setStatus(ExecutionStatusEnum.INTERRUPT.getValue());
|
|
|
+ exec.setStartTime(now);
|
|
|
+ exec.setVariables(startExec.getVariables());
|
|
|
+ exec.setBusinessKey(startExec.getBusinessKey());
|
|
|
+ exec.setStartNodeKey(startExec.getStartNodeKey());
|
|
|
+ exec.setEndNodeKey(startExec.getEndNodeKey());
|
|
|
+ exec.setCidGroupNo(startExec.getCidGroupNo());
|
|
|
+ exec.setRuntimeRangeStart(startExec.getRuntimeRangeStart());
|
|
|
+ exec.setRuntimeRangeEnd(startExec.getRuntimeRangeEnd());
|
|
|
+ exec.setIsGenerate(1);
|
|
|
+ return exec;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String buildVariables(CompanyVoiceRobotic robotic, CompanyVoiceRoboticBusiness business) {
|
|
|
+ JSONObject variables = new JSONObject(5);
|
|
|
+ variables.put("roboticId", robotic.getId());
|
|
|
+ variables.put("businessId", business.getId());
|
|
|
+ variables.put("cidGroupNo", robotic.getCidGroupNo());
|
|
|
+ variables.put("runtimeRangeStart", robotic.getRuntimeRangeStart());
|
|
|
+ variables.put("runtimeRangeEnd", robotic.getRuntimeRangeEnd());
|
|
|
+ return variables.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void persistExecLogs(List<CompanyAiWorkflowExec> workflowExecs,
|
|
|
+ List<CompanyAiWorkflowExec> startExecList) {
|
|
|
+ if (workflowExecs == null || workflowExecs.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ int rows = companyAiWorkflowExecMapper.insertBatchInfo(workflowExecs);
|
|
|
+ if (rows > 0) {
|
|
|
+ workflowExecLogBatchInsert(startExecList);
|
|
|
+ workflowExecs.forEach(exec -> exec.setStatus(ExecutionStatusEnum.FAILURE.getValue()));
|
|
|
+ workflowExecLogBatchInsert(workflowExecs);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("持久化执行日志异常,size: {}", workflowExecs.size(), e);
|
|
|
+ } finally {
|
|
|
+ workflowExecs.clear();
|
|
|
+ startExecList.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void workflowExecLogBatchInsert(List<CompanyAiWorkflowExec> workflowExecs) {
|
|
|
+ if (workflowExecs == null || workflowExecs.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CompanyAiWorkflowExecLog> batch = new ArrayList<>(workflowExecs.size());
|
|
|
+ Date date = new Date();
|
|
|
+
|
|
|
+ for (CompanyAiWorkflowExec w : workflowExecs) {
|
|
|
+ CompanyAiWorkflowExecLog execLog = new CompanyAiWorkflowExecLog();
|
|
|
+ execLog.setWorkflowInstanceId(w.getWorkflowInstanceId());
|
|
|
+ execLog.setNodeKey(w.getCurrentNodeKey());
|
|
|
+ execLog.setNodeName(w.getCurrentNodeName());
|
|
|
+ execLog.setNodeType(w.getCurrentNodeType());
|
|
|
+ execLog.setInputData(w.getVariables());
|
|
|
+ execLog.setStatus(w.getStatus());
|
|
|
+ execLog.setOutputData("null");
|
|
|
+ execLog.setStartTime(date);
|
|
|
+ execLog.setEndTime(date);
|
|
|
+ execLog.setIsGenerate(1);
|
|
|
+ batch.add(execLog);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ companyAiWorkflowExecLogMapper.batchInsert(batch);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量插入执行日志异常,size: {}", batch.size(), e);
|
|
|
+ } finally {
|
|
|
+ batch.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String generateInstanceId() {
|
|
|
+ return "wf_" + System.currentTimeMillis() + "_" +
|
|
|
+ UUID.randomUUID().toString().replace("-", "");
|
|
|
+ }
|
|
|
+}
|