|
|
@@ -0,0 +1,362 @@
|
|
|
+package com.fs.company.service.impl;
|
|
|
+
|
|
|
+import com.fs.common.core.domain.AjaxResult;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.common.utils.spring.SpringUtils;
|
|
|
+import com.fs.company.domain.*;
|
|
|
+import com.fs.company.mapper.*;
|
|
|
+import com.fs.company.param.CompanyWorkflowSaveParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowUpdateBindWCParam;
|
|
|
+import com.fs.company.service.ICompanyWorkflowService;
|
|
|
+import com.fs.company.vo.CompanyWorkflowExportVO;
|
|
|
+import com.fs.company.vo.CompanyWorkflowNodeVoiceVo;
|
|
|
+import com.fs.company.vo.CompanyWorkflowVO;
|
|
|
+import com.fs.enums.NodeTypeEnum;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * AI工作流Service业务层处理
|
|
|
+ *
|
|
|
+ * @author fs
|
|
|
+ * @date 2026-01-06
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class CompanyWorkflowServiceImpl implements ICompanyWorkflowService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowMapper companyWorkflowMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowNodeMapper companyWorkflowNodeMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowEdgeMapper companyWorkflowEdgeMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowNodeTypeMapper companyWorkflowNodeTypeMapper;
|
|
|
+
|
|
|
+ private static List<String> aiCallNodeTypes = Arrays.asList("param", "ai_chat","end");
|
|
|
+ @Override
|
|
|
+ public CompanyWorkflowVO selectCompanyWorkflowById(Long workflowId) {
|
|
|
+ CompanyWorkflow workflow = companyWorkflowMapper.selectCompanyWorkflowById(workflowId);
|
|
|
+ if (workflow == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ CompanyWorkflowVO vo = new CompanyWorkflowVO();
|
|
|
+ BeanUtils.copyProperties(workflow, vo);
|
|
|
+ vo.setNodes(companyWorkflowNodeMapper.selectCompanyWorkflowNodeByWorkflowId(workflowId));
|
|
|
+ vo.setEdges(companyWorkflowEdgeMapper.selectCompanyWorkflowEdgeByWorkflowId(workflowId));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyWorkflow> selectCompanyWorkflowList(CompanyWorkflow fsAiWorkflow) {
|
|
|
+ return companyWorkflowMapper.selectCompanyWorkflowList(fsAiWorkflow);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Long saveCompanyWorkflow(CompanyWorkflowSaveParam param) {
|
|
|
+ Date now = DateUtils.getNowDate();
|
|
|
+ Long workflowId = param.getWorkflowId();
|
|
|
+
|
|
|
+ if (workflowId == null) {
|
|
|
+ // 新增
|
|
|
+ CompanyWorkflow workflow = new CompanyWorkflow();
|
|
|
+ workflow.setWorkflowName(param.getWorkflowName());
|
|
|
+ workflow.setWorkflowDesc(param.getWorkflowDesc());
|
|
|
+ workflow.setWorkflowType(param.getWorkflowType());
|
|
|
+ workflow.setCanvasData(param.getCanvasData());
|
|
|
+ workflow.setStatus(1);
|
|
|
+ workflow.setVersion(1);
|
|
|
+ workflow.setCreateTime(now);
|
|
|
+ companyWorkflowMapper.insertCompanyWorkflow(workflow);
|
|
|
+ workflowId = workflow.getWorkflowId();
|
|
|
+ } else {
|
|
|
+ // 更新
|
|
|
+ CompanyWorkflow workflow = new CompanyWorkflow();
|
|
|
+ workflow.setWorkflowId(workflowId);
|
|
|
+ workflow.setWorkflowName(param.getWorkflowName());
|
|
|
+ workflow.setWorkflowDesc(param.getWorkflowDesc());
|
|
|
+ workflow.setWorkflowType(param.getWorkflowType());
|
|
|
+ workflow.setCanvasData(param.getCanvasData());
|
|
|
+ workflow.setUpdateTime(now);
|
|
|
+ companyWorkflowMapper.updateCompanyWorkflow(workflow);
|
|
|
+ // 删除旧的节点和连线
|
|
|
+ companyWorkflowNodeMapper.deleteCompanyWorkflowNodeByWorkflowId(workflowId);
|
|
|
+ companyWorkflowEdgeMapper.deleteCompanyWorkflowEdgeByWorkflowId(workflowId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存节点
|
|
|
+ List<CompanyWorkflowNode> nodes = param.getNodes();
|
|
|
+ if (nodes != null && !nodes.isEmpty()) {
|
|
|
+ for (CompanyWorkflowNode node : nodes) {
|
|
|
+ node.setWorkflowId(workflowId);
|
|
|
+ node.setCreateTime(now);
|
|
|
+ }
|
|
|
+ companyWorkflowNodeMapper.batchInsertCompanyWorkflowNode(nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存连线
|
|
|
+ List<CompanyWorkflowEdge> edges = param.getEdges();
|
|
|
+ if (edges != null && !edges.isEmpty()) {
|
|
|
+ for (CompanyWorkflowEdge edge : edges) {
|
|
|
+ edge.setWorkflowId(workflowId);
|
|
|
+ edge.setCreateTime(now);
|
|
|
+ }
|
|
|
+ companyWorkflowEdgeMapper.batchInsertCompanyWorkflowEdge(edges);
|
|
|
+ }
|
|
|
+
|
|
|
+ //更新工作流后,需要删除或新增录音节点对应的id
|
|
|
+
|
|
|
+ List<String> nodeKeyOlds = companyWorkflowMapper.selectCompanyWorkflowNodeByWorkflowId(workflowId);
|
|
|
+ List<Long> companyUserIds = companyWorkflowMapper.selectWorkflowCompanyUserByWfId(workflowId);
|
|
|
+
|
|
|
+ // 提取新节点的nodeKey
|
|
|
+ List<String> newNodeKeys = nodes.stream()
|
|
|
+ .filter(node -> aiCallNodeTypes.contains(node.getNodeType()))
|
|
|
+ .map(CompanyWorkflowNode::getNodeKey)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 找出新增的nodeKey(新节点中有,旧节点中没有)
|
|
|
+ List<String> nodeKeyAdd = newNodeKeys.stream()
|
|
|
+ .filter(key -> !nodeKeyOlds.contains(key))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 找出需要删除的nodeKey(旧节点中有,新节点中没有)
|
|
|
+ List<String> nodeKeyDel = nodeKeyOlds.stream()
|
|
|
+ .filter(key -> !newNodeKeys.contains(key))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!nodeKeyDel.isEmpty())companyWorkflowMapper.deleteAiWorkflowCompanyUserVoice(workflowId, nodeKeyDel);
|
|
|
+ if (!nodeKeyAdd.isEmpty())companyWorkflowMapper.addAiWorkflowCompanyUserVoice(workflowId,companyUserIds, nodeKeyAdd);
|
|
|
+ return workflowId;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int updateCompanyWorkflowStatus(Long workflowId, Integer status) {
|
|
|
+ CompanyWorkflow workflow = new CompanyWorkflow();
|
|
|
+ workflow.setWorkflowId(workflowId);
|
|
|
+ workflow.setStatus(status);
|
|
|
+ workflow.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ return companyWorkflowMapper.updateCompanyWorkflow(workflow);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public int deleteCompanyWorkflowByIds(Long[] workflowIds) {
|
|
|
+ return companyWorkflowMapper.deleteCompanyWorkflowByIds(workflowIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Long copyCompanyWorkflow(Long workflowId) {
|
|
|
+ CompanyWorkflowVO source = selectCompanyWorkflowById(workflowId);
|
|
|
+ if (source == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Date now = DateUtils.getNowDate();
|
|
|
+
|
|
|
+ // 复制工作流
|
|
|
+ CompanyWorkflow workflow = new CompanyWorkflow();
|
|
|
+ workflow.setWorkflowName(source.getWorkflowName() + "_副本");
|
|
|
+ workflow.setWorkflowDesc(source.getWorkflowDesc());
|
|
|
+ workflow.setWorkflowType(source.getWorkflowType());
|
|
|
+ workflow.setCanvasData(source.getCanvasData());
|
|
|
+ workflow.setStatus(0);
|
|
|
+ workflow.setVersion(1);
|
|
|
+ workflow.setCreateTime(now);
|
|
|
+ companyWorkflowMapper.insertCompanyWorkflow(workflow);
|
|
|
+ Long newWorkflowId = workflow.getWorkflowId();
|
|
|
+
|
|
|
+ // 复制节点
|
|
|
+ List<CompanyWorkflowNode> nodes = source.getNodes();
|
|
|
+ if (nodes != null && !nodes.isEmpty()) {
|
|
|
+ for (CompanyWorkflowNode node : nodes) {
|
|
|
+ node.setNodeId(null);
|
|
|
+ node.setWorkflowId(newWorkflowId);
|
|
|
+ node.setCreateTime(now);
|
|
|
+ }
|
|
|
+ companyWorkflowNodeMapper.batchInsertCompanyWorkflowNode(nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 复制连线
|
|
|
+ List<CompanyWorkflowEdge> edges = source.getEdges();
|
|
|
+ if (edges != null && !edges.isEmpty()) {
|
|
|
+ for (CompanyWorkflowEdge edge : edges) {
|
|
|
+ edge.setEdgeId(null);
|
|
|
+ edge.setWorkflowId(newWorkflowId);
|
|
|
+ edge.setCreateTime(now);
|
|
|
+ }
|
|
|
+ companyWorkflowEdgeMapper.batchInsertCompanyWorkflowEdge(edges);
|
|
|
+ }
|
|
|
+
|
|
|
+ return newWorkflowId;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyWorkflowNodeType> selectAllEnabledNodeTypes() {
|
|
|
+ return companyWorkflowNodeTypeMapper.selectAllEnabledNodeTypes();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CompanyWorkflowExportVO exportWorkflowJson(Long workflowId) {
|
|
|
+ CompanyWorkflowVO workflowVO = selectCompanyWorkflowById(workflowId);
|
|
|
+ if (workflowVO == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取节点类型映射
|
|
|
+// List<CompanyWorkflowNodeType> nodeTypes = companyWorkflowNodeTypeMapper.selectAllEnabledNodeTypes();
|
|
|
+// Map<String, String> typeNameMap = nodeTypes.stream()
|
|
|
+// .collect(Collectors.toMap(CompanyWorkflowNodeType::getTypeCode, CompanyWorkflowNodeType::getTypeName));
|
|
|
+
|
|
|
+ // 构建导出VO
|
|
|
+ CompanyWorkflowExportVO exportVO = new CompanyWorkflowExportVO();
|
|
|
+ exportVO.setWorkflowId(workflowVO.getWorkflowId());
|
|
|
+ exportVO.setWorkflowName(workflowVO.getWorkflowName());
|
|
|
+ exportVO.setWorkflowDesc(workflowVO.getWorkflowDesc());
|
|
|
+ exportVO.setWorkflowType(workflowVO.getWorkflowType());
|
|
|
+ exportVO.setWorkflowTypeName(getWorkflowTypeName(workflowVO.getWorkflowType()));
|
|
|
+ exportVO.setVersion(workflowVO.getVersion());
|
|
|
+
|
|
|
+ // 构建节点信息
|
|
|
+ List<CompanyWorkflowNode> nodes = workflowVO.getNodes();
|
|
|
+ Map<String, String> nodeNameMap = new HashMap<>();
|
|
|
+ List<CompanyWorkflowExportVO.NodeInfo> nodeInfoList = new ArrayList<>();
|
|
|
+ if (nodes != null) {
|
|
|
+ for (CompanyWorkflowNode node : nodes) {
|
|
|
+ nodeNameMap.put(node.getNodeKey(), node.getNodeName());
|
|
|
+ CompanyWorkflowExportVO.NodeInfo nodeInfo = new CompanyWorkflowExportVO.NodeInfo();
|
|
|
+ nodeInfo.setNodeKey(node.getNodeKey());
|
|
|
+ nodeInfo.setNodeName(node.getNodeName());
|
|
|
+ nodeInfo.setNodeType(node.getNodeType());
|
|
|
+ nodeInfo.setNodeTypeName(NodeTypeEnum.fromValue(node.getNodeType()).getDescription());
|
|
|
+ nodeInfo.setNodeConfig(node.getNodeConfig());
|
|
|
+ nodeInfo.setPosX(node.getPosX());
|
|
|
+ nodeInfo.setPosY(node.getPosY());
|
|
|
+ nodeInfo.setSortOrder(node.getSortOrder());
|
|
|
+ nodeInfoList.add(nodeInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ exportVO.setNodes(nodeInfoList);
|
|
|
+
|
|
|
+ // 构建连接信息(按sortOrder排序)
|
|
|
+ List<CompanyWorkflowEdge> edges = workflowVO.getEdges();
|
|
|
+ List<CompanyWorkflowExportVO.EdgeInfo> edgeInfoList = new ArrayList<>();
|
|
|
+ if (edges != null) {
|
|
|
+ edges.sort(Comparator.comparing(e -> e.getSortOrder() != null ? e.getSortOrder() : 0));
|
|
|
+ for (CompanyWorkflowEdge edge : edges) {
|
|
|
+ CompanyWorkflowExportVO.EdgeInfo edgeInfo = new CompanyWorkflowExportVO.EdgeInfo();
|
|
|
+ edgeInfo.setEdgeKey(edge.getEdgeKey());
|
|
|
+ edgeInfo.setEdgeLabel(edge.getEdgeLabel());
|
|
|
+ edgeInfo.setSourceNodeKey(edge.getSourceNodeKey());
|
|
|
+ edgeInfo.setSourceNodeName(nodeNameMap.get(edge.getSourceNodeKey()));
|
|
|
+ edgeInfo.setTargetNodeKey(edge.getTargetNodeKey());
|
|
|
+ edgeInfo.setTargetNodeName(nodeNameMap.get(edge.getTargetNodeKey()));
|
|
|
+ edgeInfo.setConditionExpr(edge.getConditionExpr());
|
|
|
+ edgeInfo.setSortOrder(edge.getSortOrder());
|
|
|
+ edgeInfoList.add(edgeInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ exportVO.setEdges(edgeInfoList);
|
|
|
+
|
|
|
+ return exportVO;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyUser> listCompanyUser() {
|
|
|
+ return SpringUtils.getBean(CompanyUserMapper.class).selectAllCompanyUserList();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getWorkflowTypeName(Integer workflowType) {
|
|
|
+ if (workflowType == null) return "";
|
|
|
+ switch (workflowType) {
|
|
|
+ case 1: return "对话流程";
|
|
|
+ case 2: return "任务流程";
|
|
|
+ case 3: return "审批流程";
|
|
|
+ default: return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyWorkflowNode> selectWorkflowNodesByCompanyUserId(Long companyUserId, List<String> nodeTypes) {
|
|
|
+ // 根据企业用户ID查询工作流
|
|
|
+ List<CompanyWorkflow> workflows = companyWorkflowMapper.selectCompanyWorkflowByCompanyUserId(companyUserId);
|
|
|
+ if (workflows == null || workflows.isEmpty()) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 收集所有工作流的指定类型节点
|
|
|
+ List<CompanyWorkflowNode> result = new ArrayList<>();
|
|
|
+ for (CompanyWorkflow workflow : workflows) {
|
|
|
+ List<CompanyWorkflowNode> nodes = companyWorkflowNodeMapper.selectNodesByWorkflowIdAndTypes(
|
|
|
+ workflow.getWorkflowId(), nodeTypes);
|
|
|
+ if (nodes != null) {
|
|
|
+ result.addAll(nodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int updateNodeVoiceUrl(Long nodeId, String voiceUrl, Long companyUserId) {
|
|
|
+ // 1. 查询节点是否存在
|
|
|
+ CompanyWorkflowNode node = companyWorkflowNodeMapper.selectCompanyWorkflowNodeById(nodeId);
|
|
|
+ if (node == null) {
|
|
|
+ return -1; // 节点不存在
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查询节点所属的工作流
|
|
|
+ CompanyWorkflow workflow = companyWorkflowMapper.selectCompanyWorkflowById(node.getWorkflowId());
|
|
|
+ if (workflow == null) {
|
|
|
+ return -1; // 工作流不存在
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 校验工作流是否属于该企业用户
|
|
|
+ if (workflow.getCompanyUserId() == null || !workflow.getCompanyUserId().equals(companyUserId)) {
|
|
|
+ return -2; // 无权限
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 更新voiceUrl
|
|
|
+ CompanyWorkflowNode updateNode = new CompanyWorkflowNode();
|
|
|
+ updateNode.setNodeId(nodeId);
|
|
|
+ updateNode.setVoiceUrl(voiceUrl);
|
|
|
+ return companyWorkflowNodeMapper.updateCompanyWorkflowNode(updateNode);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CompanyUser getCompanyUserById(Long id) {
|
|
|
+ return SpringUtils.getBean(CompanyUserMapper.class).selectCompanyUserById( id);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean checkCompanyUserBeUsed(Long companyUserId) {
|
|
|
+ return companyWorkflowMapper.selectCompanyWorkflowCountByCompanyUserId(companyUserId) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AjaxResult updateWorkflowBindCompanyUser(CompanyWorkflowUpdateBindWCParam param) {
|
|
|
+ if (param == null ||param.getWorkflowId() == null || param.getCompanyUserIds() == null || param.getCompanyUserIds().size() == 0) return AjaxResult.error("传参异常");
|
|
|
+ CompanyWorkflow fsAiWorkflowResult = companyWorkflowMapper.selectCompanyWorkflowById(Long.valueOf(param.getWorkflowId().toString()));
|
|
|
+ if (fsAiWorkflowResult == null)return AjaxResult.error("未查询到对应工作流,请刷新后重试");
|
|
|
+ int i = companyWorkflowMapper.insertCompanyWorkflowCompanyUser(param.getWorkflowId(),param.getCompanyUserIds());
|
|
|
+ List<CompanyWorkflowNode> fsAiWorkflowNodes = companyWorkflowNodeMapper.selectNodesByWorkflowIdAndTypes(param.getWorkflowId(), aiCallNodeTypes);
|
|
|
+ companyWorkflowMapper.insertAiWorkflowCompanyUserVoice(param.getWorkflowId(), param.getCompanyUserIds(), fsAiWorkflowNodes);
|
|
|
+ return AjaxResult.success("绑定成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AjaxResult getBindCompanyUserByWorkflowId(Long workflowId) {
|
|
|
+ CompanyWorkflow fsAiWorkflow = companyWorkflowMapper.selectCompanyWorkflowById(workflowId);
|
|
|
+ if (fsAiWorkflow == null) return AjaxResult.error("工作流不存在");
|
|
|
+ return AjaxResult.success(companyWorkflowMapper.getBindCompanyUserByWorkflowId(workflowId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyWorkflowNodeVoiceVo> getMyWorkflowNodes(Long companyUserId) {
|
|
|
+ return companyWorkflowMapper.getMyWorkflowNodes(companyUserId);
|
|
|
+ }
|
|
|
+}
|