|
|
@@ -0,0 +1,598 @@
|
|
|
+package com.fs.company.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.fs.common.core.domain.AjaxResult;
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.common.utils.spring.SpringUtils;
|
|
|
+import com.fs.company.domain.CompanyWorkflowLobster;
|
|
|
+import com.fs.company.domain.CompanyWorkflowLobsterEdge;
|
|
|
+import com.fs.company.domain.CompanyWorkflowLobsterNode;
|
|
|
+import com.fs.company.domain.CompanyWorkflowLobsterRecord;
|
|
|
+import com.fs.company.domain.CompanyWorkflowLobsterVariable;
|
|
|
+import com.fs.company.mapper.CompanyWorkflowLobsterEdgeMapper;
|
|
|
+import com.fs.company.mapper.CompanyWorkflowLobsterMapper;
|
|
|
+import com.fs.company.mapper.CompanyWorkflowLobsterNodeMapper;
|
|
|
+import com.fs.company.mapper.CompanyWorkflowLobsterRecordMapper;
|
|
|
+import com.fs.company.mapper.CompanyWorkflowLobsterVariableMapper;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterCanvasParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterConfirmParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterEdgeParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterGenerateParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterNodeParam;
|
|
|
+import com.fs.company.param.CompanyWorkflowLobsterVariableParam;
|
|
|
+import com.fs.company.service.ICompanyWorkflowLobsterService;
|
|
|
+import com.fs.fastgptApi.param.ChatParam;
|
|
|
+import com.fs.fastgptApi.service.ChatService;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobsterService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowLobsterMapper lobsterMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowLobsterNodeMapper nodeMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowLobsterVariableMapper variableMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowLobsterRecordMapper recordMapper;
|
|
|
+ @Autowired
|
|
|
+ private CompanyWorkflowLobsterEdgeMapper edgeMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CompanyWorkflowLobster> listTemplate(Long companyId, Integer page, Integer size) {
|
|
|
+ List<CompanyWorkflowLobster> all = lobsterMapper.selectTemplateList(companyId);
|
|
|
+ int start = Math.max((page - 1) * size, 0);
|
|
|
+ int end = Math.min(start + size, all.size());
|
|
|
+ if (start >= all.size()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ return all.subList(start, end);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final String LOBSTER_KEY = "fastgpt-lDP6kVelHf2p8j80vfz2Kl7g9PjacwJoTmCplEBGWBaGMCRtv7SueW5mZ4iXe";
|
|
|
+ private static final ObjectMapper mapper = new ObjectMapper();
|
|
|
+ private static final String AI_API = "http://129.28.170.206:3000/api";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String generate(Long companyId, String userName, CompanyWorkflowLobsterGenerateParam param) {
|
|
|
+ Long l = System.currentTimeMillis();
|
|
|
+ String recordNo = "LOB_" + l;
|
|
|
+ CompanyWorkflowLobsterRecord record = new CompanyWorkflowLobsterRecord();
|
|
|
+ record.setCompanyId(companyId);
|
|
|
+ record.setRecordNo(recordNo);
|
|
|
+ record.setRequirement(param.getRequirement());
|
|
|
+ record.setSelectedApiIds(param.getSelectedApiIds() == null ? null : param.getSelectedApiIds().stream().map(String::valueOf).collect(Collectors.joining(",")));
|
|
|
+ record.setStatus(1);
|
|
|
+ record.setCreateBy(userName);
|
|
|
+ record.setCreateTime(DateUtils.getNowDate());
|
|
|
+ record.setUpdateBy(userName);
|
|
|
+ record.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ record.setDelFlag(0);
|
|
|
+ String requestStr = "{ \"userContent\": \""+param.getRequirement()+"\", \"aiContent\": null }";
|
|
|
+ R r = callAiService(requestStr, l, LOBSTER_KEY);
|
|
|
+// System.out.println(r);
|
|
|
+ record.setResultJson(buildResultJsonFromAi(r, param.getRequirement()));
|
|
|
+ recordMapper.insertRecord(record);
|
|
|
+ return recordNo;
|
|
|
+ }
|
|
|
+ private static R callAiService(String requestParam, Long logId, String appKey) {
|
|
|
+ try {
|
|
|
+ ChatParam param = new ChatParam();
|
|
|
+ param.setChatId(logId.toString());
|
|
|
+ param.setStream(false);
|
|
|
+ param.setDetail(true);
|
|
|
+ ChatParam.Message message = new ChatParam.Message();
|
|
|
+ List<ChatParam.Message> messageList = new ArrayList<ChatParam.Message>();
|
|
|
+ message.setContent(requestParam);
|
|
|
+ message.setRole("user");
|
|
|
+ messageList.add(message);
|
|
|
+ param.setMessages(messageList);
|
|
|
+ ChatService chatService = SpringUtils.getBean(ChatService.class);
|
|
|
+
|
|
|
+ return chatService.initiatingTakeChat(param, AI_API, appKey);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("AI服务调用失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getResultDetail(Long companyId, String recordId) {
|
|
|
+ CompanyWorkflowLobsterRecord record = recordMapper.selectByRecordNo(recordId, companyId);
|
|
|
+ if (record == null) {
|
|
|
+ return new HashMap<String, Object>() {{
|
|
|
+ put("status", 2);
|
|
|
+ put("errorMsg", "record不存在");
|
|
|
+ }};
|
|
|
+ }
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("status", record.getStatus());
|
|
|
+ map.put("errorMsg", record.getErrorMsg());
|
|
|
+ if (record.getResultJson() != null) {
|
|
|
+ JSONObject resultJson = JSONUtil.parseObj(record.getResultJson());
|
|
|
+ map.putAll(resultJson);
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public AjaxResult confirmRaw(Long companyId, String userName, String recordId) {
|
|
|
+ CompanyWorkflowLobsterRecord record = recordMapper.selectByRecordNo(recordId, companyId);
|
|
|
+ if (record == null) {
|
|
|
+ return AjaxResult.error("record不存在");
|
|
|
+ }
|
|
|
+ if (record.getResultJson() == null) {
|
|
|
+ return AjaxResult.error("生成结果为空");
|
|
|
+ }
|
|
|
+ CompanyWorkflowLobsterConfirmParam param = JSONUtil.toBean(record.getResultJson(), CompanyWorkflowLobsterConfirmParam.class);
|
|
|
+ saveWorkflow(companyId, userName, param);
|
|
|
+ record.setStatus(3);
|
|
|
+ record.setUpdateBy(userName);
|
|
|
+ record.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ recordMapper.updateRecord(record);
|
|
|
+ return AjaxResult.success("保存成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public AjaxResult confirmEdited(Long companyId, String userName, String recordId, CompanyWorkflowLobsterConfirmParam param) {
|
|
|
+ CompanyWorkflowLobsterRecord record = recordMapper.selectByRecordNo(recordId, companyId);
|
|
|
+ if (record == null) {
|
|
|
+ return AjaxResult.error("record不存在");
|
|
|
+ }
|
|
|
+ saveWorkflow(companyId, userName, param);
|
|
|
+ record.setStatus(3);
|
|
|
+ record.setUpdateBy(userName);
|
|
|
+ record.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ recordMapper.updateRecord(record);
|
|
|
+ return AjaxResult.success("保存成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> previewTemplate(Long companyId, Long templateId) {
|
|
|
+ CompanyWorkflowLobster template = lobsterMapper.selectById(templateId);
|
|
|
+ if (template == null || !Objects.equals(template.getCompanyId(), companyId) || Objects.equals(template.getDelFlag(), 1)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<CompanyWorkflowLobsterVariable> variables = variableMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterVariable>()
|
|
|
+ .eq(CompanyWorkflowLobsterVariable::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterVariable::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterVariable::getId)
|
|
|
+ );
|
|
|
+ List<CompanyWorkflowLobsterNode> nodes = nodeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterNode>()
|
|
|
+ .eq(CompanyWorkflowLobsterNode::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterNode::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterNode::getSortNo)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterNode::getId)
|
|
|
+ );
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("template", template);
|
|
|
+ result.put("variables", variables);
|
|
|
+ result.put("nodes", nodes);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public AjaxResult deleteTemplate(Long companyId, String userName, Long templateId) {
|
|
|
+ CompanyWorkflowLobster template = lobsterMapper.selectById(templateId);
|
|
|
+ if (template == null || !Objects.equals(template.getCompanyId(), companyId) || Objects.equals(template.getDelFlag(), 1)) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ template.setDelFlag(1);
|
|
|
+ template.setUpdateBy(userName);
|
|
|
+ template.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ lobsterMapper.updateById(template);
|
|
|
+ variableMapper.deleteByWorkflowId(templateId);
|
|
|
+ nodeMapper.deleteByWorkflowId(templateId);
|
|
|
+ edgeMapper.deleteByWorkflowId(templateId); // 删除关联的连线数据
|
|
|
+ return AjaxResult.success("删除成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public AjaxResult updateTemplate(Long companyId, String userName, Long templateId, CompanyWorkflowLobsterConfirmParam param) {
|
|
|
+ CompanyWorkflowLobster template = lobsterMapper.selectById(templateId);
|
|
|
+ if (template == null || !Objects.equals(template.getCompanyId(), companyId) || Objects.equals(template.getDelFlag(), 1)) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ template.setTemplateName(param.getTemplateName());
|
|
|
+ template.setIndustryType(param.getIndustryType());
|
|
|
+ template.setDescription(param.getDescription());
|
|
|
+ template.setVersion(template.getVersion() == null ? 1 : template.getVersion() + 1);
|
|
|
+ template.setUpdateBy(userName);
|
|
|
+ template.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ lobsterMapper.updateById(template);
|
|
|
+
|
|
|
+ // 先逻辑删除旧节点与旧变量,再写入新内容
|
|
|
+ variableMapper.deleteByWorkflowId(templateId);
|
|
|
+ nodeMapper.deleteByWorkflowId(templateId);
|
|
|
+ saveWorkflowDetails(templateId, userName, param);
|
|
|
+ return AjaxResult.success("修改成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getTemplate(Long companyId, Long templateId) {
|
|
|
+ CompanyWorkflowLobster template = lobsterMapper.selectById(templateId);
|
|
|
+ if (template == null || !Objects.equals(template.getCompanyId(), companyId) || Objects.equals(template.getDelFlag(), 1)) {
|
|
|
+ return new HashMap<String, Object>() {{
|
|
|
+ put("status", 2);
|
|
|
+ put("errorMsg", "模板不存在");
|
|
|
+ }};
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CompanyWorkflowLobsterVariable> variables = variableMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterVariable>()
|
|
|
+ .eq(CompanyWorkflowLobsterVariable::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterVariable::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterVariable::getId)
|
|
|
+ );
|
|
|
+ List<CompanyWorkflowLobsterNode> nodes = nodeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterNode>()
|
|
|
+ .eq(CompanyWorkflowLobsterNode::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterNode::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterNode::getSortNo)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterNode::getId)
|
|
|
+ );
|
|
|
+ // 查询连线数据
|
|
|
+ List<CompanyWorkflowLobsterEdge> edges = edgeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterEdge>()
|
|
|
+ .eq(CompanyWorkflowLobsterEdge::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterEdge::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterEdge::getSortNo)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterEdge::getId)
|
|
|
+ );
|
|
|
+
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("status", 3);
|
|
|
+ map.put("errorMsg", null);
|
|
|
+ map.put("templateId", template.getId());
|
|
|
+ map.put("templateCode", template.getTemplateCode());
|
|
|
+ map.put("templateName", template.getTemplateName());
|
|
|
+ map.put("industryType", template.getIndustryType());
|
|
|
+ map.put("description", template.getDescription());
|
|
|
+ map.put("canvasData", template.getCanvasData()); // 添加画布数据
|
|
|
+ map.put("variables", variables);
|
|
|
+ map.put("nodes", nodes);
|
|
|
+ map.put("edges", edges); // 添加连线数据
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String buildDefaultResultJson(String requirement) {
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("templateName", "AI生成工作流方案");
|
|
|
+ result.put("industryType", "general");
|
|
|
+ result.put("description", requirement == null ? "" : requirement);
|
|
|
+ result.put("variables", Arrays.asList(
|
|
|
+ variableMap("customer_name", "客户姓名", "string", "user_profile", 1, "客户名称"),
|
|
|
+ variableMap("follow_date", "跟进日期", "date", "manual", 0, "计划跟进时间")
|
|
|
+ ));
|
|
|
+ result.put("nodes", Arrays.asList(
|
|
|
+ nodeMap("START", "开始节点", 1, 1, "MSG_1", "", "", "{}"),
|
|
|
+ nodeMap("MSG_1", "消息节点", 2, 2, "END", "生成失败,请重新编写提示词", "", "{}"),
|
|
|
+ nodeMap("END", "结束节点", 5, 3, "", "", "", "{}")
|
|
|
+ ));
|
|
|
+ // 默认连线:START -> MSG_1 -> END
|
|
|
+ result.put("edges", Arrays.asList(
|
|
|
+ edgeMap("EDGE_0", "START", "MSG_1", "right", "left", "", "#999", ""),
|
|
|
+ edgeMap("EDGE_1", "MSG_1", "END", "right", "left", "", "#999", "")
|
|
|
+ ));
|
|
|
+ return JSONUtil.toJsonStr(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按 r.data.choices[0].message.content 结构提取 aiContent 并生成工作流模板JSON
|
|
|
+ */
|
|
|
+ private String buildResultJsonFromAi(R aiResponse, String requirement) {
|
|
|
+ try {
|
|
|
+ Object dataObj = aiResponse.get("data");
|
|
|
+ if (dataObj == null) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<?, ?> dataMap = mapper.convertValue(dataObj, Map.class);
|
|
|
+ Object choicesObj = dataMap.get("choices");
|
|
|
+ if (!(choicesObj instanceof List) || ((List<?>) choicesObj).isEmpty()) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<?, ?> firstChoice = mapper.convertValue(((List<?>) choicesObj).get(0), Map.class);
|
|
|
+ Map<?, ?> message = mapper.convertValue(firstChoice.get("message"), Map.class);
|
|
|
+ String content = message.get("content") == null ? null : String.valueOf(message.get("content"));
|
|
|
+ if (content == null || content.trim().isEmpty()) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject contentJson = JSONUtil.parseObj(content);
|
|
|
+ String userContent = contentJson.getStr("userContent");
|
|
|
+ String industryType = (userContent == null || userContent.trim().isEmpty()) ? "general" : userContent;
|
|
|
+ List<Object> aiContentList = contentJson.getJSONArray("aiContent");
|
|
|
+ if (aiContentList == null || aiContentList.isEmpty()) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Map<String, Object>> nodes = new ArrayList<>();
|
|
|
+ nodes.add(nodeMap("START", "开始节点", 1, 1, "", "", "", "{}"));
|
|
|
+
|
|
|
+ int sortNo = 2;
|
|
|
+ List<String> dayCodes = new ArrayList<>();
|
|
|
+ for (Object item : aiContentList) {
|
|
|
+ Map<?, ?> itemMap = mapper.convertValue(item, Map.class);
|
|
|
+ Object addDayObj = itemMap.get("addDay");
|
|
|
+ if (addDayObj == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String day = String.valueOf(addDayObj).trim();
|
|
|
+ if (day.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String nodeCode = "DAY_" + day;
|
|
|
+ dayCodes.add(nodeCode);
|
|
|
+ String template = itemMap.get("content") == null ? "" : String.valueOf(itemMap.get("content"));
|
|
|
+ nodes.add(nodeMap(nodeCode, "第" + day + "天", 2, sortNo++, "", template, "", "{}"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dayCodes.isEmpty()) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成节点之间的连线
|
|
|
+ List<Map<String, Object>> edges = new ArrayList<>();
|
|
|
+
|
|
|
+ // START -> 第一个DAY节点
|
|
|
+ if (!dayCodes.isEmpty()) {
|
|
|
+ edges.add(edgeMap("EDGE_START_0", "START", dayCodes.get(0), "right", "left", "", "#999", ""));
|
|
|
+ }
|
|
|
+
|
|
|
+ // DAY节点之间的连接
|
|
|
+ for (int i = 0; i < dayCodes.size(); i++) {
|
|
|
+ String currentCode = dayCodes.get(i);
|
|
|
+ String nextCode = (i == dayCodes.size() - 1) ? "END" : dayCodes.get(i + 1);
|
|
|
+
|
|
|
+ // 更新节点的nextNodeCode
|
|
|
+ nodes.get(i + 1).put("nextNodeCode", nextCode);
|
|
|
+
|
|
|
+ // 添加连线
|
|
|
+ String edgeKey = "EDGE_" + i;
|
|
|
+ edges.add(edgeMap(edgeKey, currentCode, nextCode, "right", "left", "", "#999", ""));
|
|
|
+ }
|
|
|
+
|
|
|
+ nodes.add(nodeMap("END", "结束节点", 5, sortNo, "", "", "", "{}"));
|
|
|
+
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("templateName", "AI生成工作流方案");
|
|
|
+ result.put("industryType", industryType);
|
|
|
+ result.put("description", requirement == null ? "" : requirement);
|
|
|
+ result.put("variables", Arrays.asList(
|
|
|
+ variableMap("customer_name", "客户姓名", "string", "user_profile", 1, "客户名称"),
|
|
|
+ variableMap("follow_date", "跟进日期", "date", "manual", 0, "计划跟进时间")
|
|
|
+ ));
|
|
|
+ result.put("nodes", nodes);
|
|
|
+ result.put("edges", edges); // 添加连线数据
|
|
|
+ return JSONUtil.toJsonStr(result);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ return buildDefaultResultJson(requirement);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> variableMap(String varCode, String varName, String varType, String sourceType, Integer required, String description) {
|
|
|
+ Map<String, Object> m = new HashMap<>();
|
|
|
+ m.put("varCode", varCode);
|
|
|
+ m.put("varName", varName);
|
|
|
+ m.put("varType", varType);
|
|
|
+ m.put("sourceType", sourceType);
|
|
|
+ m.put("required", required);
|
|
|
+ m.put("description", description);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> nodeMap(String nodeCode, String nodeName, Integer nodeType, Integer sortNo, String nextNodeCode, String messageTemplate, String conditionExpr, String nodeConfig) {
|
|
|
+ Map<String, Object> m = new HashMap<>();
|
|
|
+ m.put("nodeCode", nodeCode);
|
|
|
+ m.put("nodeName", nodeName);
|
|
|
+ m.put("nodeType", nodeType);
|
|
|
+ m.put("sortNo", sortNo);
|
|
|
+ m.put("nextNodeCode", nextNodeCode);
|
|
|
+ m.put("messageTemplate", messageTemplate);
|
|
|
+ m.put("conditionExpr", conditionExpr);
|
|
|
+ m.put("nodeConfig", nodeConfig);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> edgeMap(String edgeKey, String sourceNodeCode, String targetNodeCode,
|
|
|
+ String sourcePort, String targetPort,
|
|
|
+ String edgeLabel, String edgeColor, String conditionExpr) {
|
|
|
+ Map<String, Object> m = new HashMap<>();
|
|
|
+ m.put("edgeKey", edgeKey);
|
|
|
+ m.put("sourceNodeCode", sourceNodeCode);
|
|
|
+ m.put("targetNodeCode", targetNodeCode);
|
|
|
+ m.put("sourcePort", sourcePort);
|
|
|
+ m.put("targetPort", targetPort);
|
|
|
+ m.put("edgeLabel", edgeLabel);
|
|
|
+ m.put("edgeColor", edgeColor);
|
|
|
+ m.put("conditionExpr", conditionExpr);
|
|
|
+ m.put("sortNo", 0);
|
|
|
+ m.put("delFlag", 0);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveWorkflow(Long companyId, String userName, CompanyWorkflowLobsterConfirmParam param) {
|
|
|
+ CompanyWorkflowLobster entity = new CompanyWorkflowLobster();
|
|
|
+ entity.setCompanyId(companyId);
|
|
|
+ entity.setTemplateCode("LOB_" + System.currentTimeMillis());
|
|
|
+ entity.setTemplateName(param.getTemplateName());
|
|
|
+ entity.setIndustryType(param.getIndustryType());
|
|
|
+ entity.setDescription(param.getDescription());
|
|
|
+ entity.setStatus(0);
|
|
|
+ entity.setVersion(1);
|
|
|
+ entity.setDelFlag(0);
|
|
|
+ entity.setCreateBy(userName);
|
|
|
+ entity.setCreateTime(DateUtils.getNowDate());
|
|
|
+ entity.setUpdateBy(userName);
|
|
|
+ entity.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ lobsterMapper.insertTemplate(entity);
|
|
|
+
|
|
|
+ Long workflowId = entity.getId();
|
|
|
+ if (workflowId == null) {
|
|
|
+ throw new RuntimeException("保存模板失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ saveWorkflowDetails(workflowId, userName, param);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveWorkflowDetails(Long workflowId, String userName, CompanyWorkflowLobsterConfirmParam param) {
|
|
|
+ // 保存变量
|
|
|
+ List<CompanyWorkflowLobsterVariableParam> vars = param.getVariables();
|
|
|
+ if (vars != null && !vars.isEmpty()) {
|
|
|
+ List<CompanyWorkflowLobsterVariable> varEntities = new ArrayList<>();
|
|
|
+ for (CompanyWorkflowLobsterVariableParam it : vars) {
|
|
|
+ CompanyWorkflowLobsterVariable v = new CompanyWorkflowLobsterVariable();
|
|
|
+ BeanUtils.copyProperties(it, v);
|
|
|
+ v.setWorkflowId(workflowId);
|
|
|
+ v.setDelFlag(0);
|
|
|
+ v.setCreateBy(userName);
|
|
|
+ v.setCreateTime(DateUtils.getNowDate());
|
|
|
+ v.setUpdateBy(userName);
|
|
|
+ v.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ varEntities.add(v);
|
|
|
+ }
|
|
|
+ variableMapper.batchInsert(varEntities);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存节点
|
|
|
+ List<CompanyWorkflowLobsterNodeParam> nodes = param.getNodes();
|
|
|
+ if (nodes != null && !nodes.isEmpty()) {
|
|
|
+ List<CompanyWorkflowLobsterNode> nodeEntities = new ArrayList<>();
|
|
|
+ int idx = 1;
|
|
|
+ for (CompanyWorkflowLobsterNodeParam it : nodes) {
|
|
|
+ CompanyWorkflowLobsterNode n = new CompanyWorkflowLobsterNode();
|
|
|
+ BeanUtils.copyProperties(it, n);
|
|
|
+ n.setWorkflowId(workflowId);
|
|
|
+ if (n.getSortNo() == null) {
|
|
|
+ n.setSortNo(idx++);
|
|
|
+ }
|
|
|
+ n.setDelFlag(0);
|
|
|
+ n.setCreateBy(userName);
|
|
|
+ n.setCreateTime(DateUtils.getNowDate());
|
|
|
+ n.setUpdateBy(userName);
|
|
|
+ n.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ nodeEntities.add(n);
|
|
|
+ }
|
|
|
+ nodeMapper.batchInsert(nodeEntities);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存连线
|
|
|
+ List<CompanyWorkflowLobsterEdgeParam> edges = param.getEdges();
|
|
|
+ if (edges != null && !edges.isEmpty()) {
|
|
|
+ List<CompanyWorkflowLobsterEdge> edgeEntities = new ArrayList<>();
|
|
|
+ int idx = 0;
|
|
|
+ for (CompanyWorkflowLobsterEdgeParam it : edges) {
|
|
|
+ CompanyWorkflowLobsterEdge e = new CompanyWorkflowLobsterEdge();
|
|
|
+ BeanUtils.copyProperties(it, e);
|
|
|
+ e.setWorkflowId(workflowId);
|
|
|
+ if (e.getSortNo() == null) {
|
|
|
+ e.setSortNo(idx++);
|
|
|
+ }
|
|
|
+ e.setDelFlag(0);
|
|
|
+ e.setCreateBy(userName);
|
|
|
+ e.setCreateTime(DateUtils.getNowDate());
|
|
|
+ e.setUpdateBy(userName);
|
|
|
+ e.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ edgeEntities.add(e);
|
|
|
+ }
|
|
|
+ edgeMapper.batchInsert(edgeEntities);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public AjaxResult saveCanvas(Long companyId, String userName, Long templateId, CompanyWorkflowLobsterCanvasParam param) {
|
|
|
+ // 验证模板是否存在
|
|
|
+ CompanyWorkflowLobster template = lobsterMapper.selectById(templateId);
|
|
|
+ if (template == null || !Objects.equals(template.getCompanyId(), companyId) || Objects.equals(template.getDelFlag(), 1)) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新模板基本信息和画布数据
|
|
|
+ template.setTemplateName(param.getTemplateName());
|
|
|
+ template.setIndustryType(param.getIndustryType());
|
|
|
+ template.setDescription(param.getDescription());
|
|
|
+ template.setCanvasData(param.getCanvasData()); // 保存画布JSON数据
|
|
|
+ template.setVersion(template.getVersion() == null ? 1 : template.getVersion() + 1);
|
|
|
+ template.setUpdateBy(userName);
|
|
|
+ template.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ lobsterMapper.updateById(template);
|
|
|
+
|
|
|
+ // 先逻辑删除旧数据
|
|
|
+ variableMapper.deleteByWorkflowId(templateId);
|
|
|
+ nodeMapper.deleteByWorkflowId(templateId);
|
|
|
+ edgeMapper.deleteByWorkflowId(templateId);
|
|
|
+
|
|
|
+ // 保存变量
|
|
|
+ if (param.getVariables() != null && !param.getVariables().isEmpty()) {
|
|
|
+ variableMapper.batchInsert(param.getVariables().stream().map(v -> {
|
|
|
+ CompanyWorkflowLobsterVariable entity = new CompanyWorkflowLobsterVariable();
|
|
|
+ BeanUtils.copyProperties(v, entity);
|
|
|
+ entity.setWorkflowId(templateId);
|
|
|
+ entity.setDelFlag(0);
|
|
|
+ entity.setCreateBy(userName);
|
|
|
+ entity.setCreateTime(DateUtils.getNowDate());
|
|
|
+ entity.setUpdateBy(userName);
|
|
|
+ entity.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ return entity;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存节点(包含位置信息)
|
|
|
+ if (param.getNodes() != null && !param.getNodes().isEmpty()) {
|
|
|
+ nodeMapper.batchInsert(param.getNodes().stream().map(n -> {
|
|
|
+ CompanyWorkflowLobsterNode entity = new CompanyWorkflowLobsterNode();
|
|
|
+ BeanUtils.copyProperties(n, entity);
|
|
|
+ entity.setWorkflowId(templateId);
|
|
|
+ if (entity.getSortNo() == null) {
|
|
|
+ entity.setSortNo(0);
|
|
|
+ }
|
|
|
+ entity.setDelFlag(0);
|
|
|
+ entity.setCreateBy(userName);
|
|
|
+ entity.setCreateTime(DateUtils.getNowDate());
|
|
|
+ entity.setUpdateBy(userName);
|
|
|
+ entity.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ return entity;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存连线
|
|
|
+ if (param.getEdges() != null && !param.getEdges().isEmpty()) {
|
|
|
+ edgeMapper.batchInsert(param.getEdges().stream().map(e -> {
|
|
|
+ CompanyWorkflowLobsterEdge entity = new CompanyWorkflowLobsterEdge();
|
|
|
+ BeanUtils.copyProperties(e, entity);
|
|
|
+ entity.setWorkflowId(templateId);
|
|
|
+ if (entity.getSortNo() == null) {
|
|
|
+ entity.setSortNo(0);
|
|
|
+ }
|
|
|
+ entity.setDelFlag(0);
|
|
|
+ entity.setCreateBy(userName);
|
|
|
+ entity.setCreateTime(DateUtils.getNowDate());
|
|
|
+ entity.setUpdateBy(userName);
|
|
|
+ entity.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ return entity;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+
|
|
|
+ return AjaxResult.success("画布保存成功");
|
|
|
+ }
|
|
|
+}
|