|
|
@@ -26,6 +26,7 @@ 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.company.vo.CompanyWorkflowLobsterDetailVO;
|
|
|
import com.fs.fastgptApi.param.ChatParam;
|
|
|
import com.fs.fastgptApi.service.ChatService;
|
|
|
import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
|
|
|
@@ -33,9 +34,11 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
|
import java.sql.Time;
|
|
|
import java.util.*;
|
|
|
@@ -60,19 +63,22 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
private CompanyTagTemplateBindingMapper tagBindingMapper;
|
|
|
|
|
|
@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);
|
|
|
+ public Map<String, Object> listTemplate(Long companyId, Integer page, Integer size) {
|
|
|
+ long total = lobsterMapper.countTemplateList(companyId);
|
|
|
+ List<CompanyWorkflowLobster> list = lobsterMapper.selectTemplatePage(companyId, (page - 1) * size, size);
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("total", total);
|
|
|
+ result.put("list", list);
|
|
|
+ result.put("page", page);
|
|
|
+ result.put("size", size);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
- private static final String LOBSTER_KEY = "fastgpt-lDP6kVelHf2p8j80vfz2Kl7g9PjacwJoTmCplEBGWBaGMCRtv7SueW5mZ4iXe";
|
|
|
+ @Value("${lobster.ai.key:fastgpt-lDP6kVelHf2p8j80vfz2Kl7g9PjacwJoTmCplEBGWBaGMCRtv7SueW5mZ4iXe}")
|
|
|
+ private String lobsterKey;
|
|
|
+ @Value("${lobster.ai.url:http://129.28.170.206:3000/api}")
|
|
|
+ private String aiApi;
|
|
|
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) {
|
|
|
@@ -83,38 +89,57 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
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.setStatus(0);
|
|
|
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);
|
|
|
- log.info("流程图生成成功: {}", param.getRequirement());
|
|
|
-// System.out.println(r);
|
|
|
- record.setResultJson(buildResultJsonFromAi(r, param.getRequirement()));
|
|
|
+ try {
|
|
|
+ R r = callAiService(requestStr, l, lobsterKey);
|
|
|
+ log.info("AI生成成功: {}", param.getRequirement());
|
|
|
+ record.setResultJson(buildResultJsonFromAi(r, param.getRequirement()));
|
|
|
+ record.setStatus(1);
|
|
|
+ record.setTokenCount(extractTokenCount(r));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("AI生成失败: {}", param.getRequirement(), e);
|
|
|
+ record.setStatus(2);
|
|
|
+ record.setErrorMsg("AI服务调用失败: " + e.getMessage());
|
|
|
+ record.setResultJson(buildDefaultResultJson(param.getRequirement()));
|
|
|
+ }
|
|
|
recordMapper.insertRecord(record);
|
|
|
return recordNo;
|
|
|
}
|
|
|
- public static R callAiService(String requestParam, Long logId, String appKey) {
|
|
|
+
|
|
|
+ private Integer extractTokenCount(R r) {
|
|
|
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);
|
|
|
- }
|
|
|
+ Object dataObj = r.get("data");
|
|
|
+ if (dataObj != null) {
|
|
|
+ Map<?, ?> dataMap = mapper.convertValue(dataObj, Map.class);
|
|
|
+ Object usage = dataMap.get("usage");
|
|
|
+ if (usage instanceof Map) {
|
|
|
+ Object total = ((Map<?, ?>) usage).get("totalTokens");
|
|
|
+ return total != null ? Integer.parseInt(String.valueOf(total)) : null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception ignore) {}
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private R callAiService(String requestParam, Long logId, String appKey) {
|
|
|
+ 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, aiApi, appKey);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -171,7 +196,7 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Map<String, Object> previewTemplate(Long companyId, Long templateId) {
|
|
|
+ public CompanyWorkflowLobsterDetailVO 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;
|
|
|
@@ -189,11 +214,19 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
.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;
|
|
|
+ List<CompanyWorkflowLobsterEdge> edges = edgeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CompanyWorkflowLobsterEdge>()
|
|
|
+ .eq(CompanyWorkflowLobsterEdge::getWorkflowId, templateId)
|
|
|
+ .eq(CompanyWorkflowLobsterEdge::getDelFlag, 0)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterEdge::getSortNo)
|
|
|
+ .orderByAsc(CompanyWorkflowLobsterEdge::getId)
|
|
|
+ );
|
|
|
+ CompanyWorkflowLobsterDetailVO vo = new CompanyWorkflowLobsterDetailVO();
|
|
|
+ BeanUtils.copyProperties(template, vo);
|
|
|
+ vo.setVariables(variables);
|
|
|
+ vo.setNodes(nodes);
|
|
|
+ vo.setEdges(edges);
|
|
|
+ return vo;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -236,13 +269,10 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Map<String, Object> getTemplate(Long companyId, Long templateId) {
|
|
|
+ public CompanyWorkflowLobsterDetailVO 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", "模板不存在");
|
|
|
- }};
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
List<CompanyWorkflowLobsterVariable> variables = variableMapper.selectList(
|
|
|
@@ -258,7 +288,6 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
.orderByAsc(CompanyWorkflowLobsterNode::getSortNo)
|
|
|
.orderByAsc(CompanyWorkflowLobsterNode::getId)
|
|
|
);
|
|
|
- // 查询连线数据
|
|
|
List<CompanyWorkflowLobsterEdge> edges = edgeMapper.selectList(
|
|
|
new LambdaQueryWrapper<CompanyWorkflowLobsterEdge>()
|
|
|
.eq(CompanyWorkflowLobsterEdge::getWorkflowId, templateId)
|
|
|
@@ -267,19 +296,12 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
.orderByAsc(CompanyWorkflowLobsterEdge::getId)
|
|
|
);
|
|
|
|
|
|
- Map<String, Object> map = new HashMap<>();
|
|
|
- map.put("status", template.getStatus());
|
|
|
- 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;
|
|
|
+ CompanyWorkflowLobsterDetailVO vo = new CompanyWorkflowLobsterDetailVO();
|
|
|
+ BeanUtils.copyProperties(template, vo);
|
|
|
+ vo.setVariables(variables);
|
|
|
+ vo.setNodes(nodes);
|
|
|
+ vo.setEdges(edges);
|
|
|
+ return vo;
|
|
|
}
|
|
|
|
|
|
private String buildDefaultResultJson(String requirement) {
|
|
|
@@ -534,138 +556,87 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
|
|
|
@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("模板不存在");
|
|
|
}
|
|
|
|
|
|
- // 检查是否存在绑定的标签,有则提示先删除绑定
|
|
|
List<CompanyTagTemplateBinding> bindings = tagBindingMapper.selectBindingList(companyId, null, templateId);
|
|
|
if (bindings != null && !bindings.isEmpty()) {
|
|
|
return AjaxResult.error("已存在绑定标签,请先删除绑定关系");
|
|
|
}
|
|
|
|
|
|
- // 更新模板基本信息和画布数据
|
|
|
template.setTemplateName(param.getTemplateName());
|
|
|
template.setIndustryType(param.getIndustryType());
|
|
|
template.setDescription(param.getDescription());
|
|
|
- template.setCanvasData(param.getCanvasData()); // 保存画布JSON数据
|
|
|
+ template.setCanvasData(param.getCanvasData());
|
|
|
template.setVersion(template.getVersion() == null ? 1 : template.getVersion() + 1);
|
|
|
template.setUpdateBy(userName);
|
|
|
template.setUpdateTime(DateUtils.getNowDate());
|
|
|
lobsterMapper.updateById(template);
|
|
|
|
|
|
- // 查询旧数据
|
|
|
- List<CompanyWorkflowLobsterVariable> oldVariables = variableMapper.selectByWorkflowId(templateId);
|
|
|
- List<CompanyWorkflowLobsterNode> oldNodes = nodeMapper.selectByWorkflowId(templateId);
|
|
|
- List<CompanyWorkflowLobsterEdge> oldEdges = edgeMapper.selectByWorkflowId(templateId);
|
|
|
-
|
|
|
Date now = DateUtils.getNowDate();
|
|
|
|
|
|
- // ==================== 变量:有id更新 / 无id新增 / 旧的且不在新参数中的逻辑删除 ====================
|
|
|
- Set<Long> newVarIds = new HashSet<>();
|
|
|
+ // 变量:先删后插(参数使用 Param 对象,避免 Domain 字段污染)
|
|
|
+ variableMapper.deleteByWorkflowId(templateId);
|
|
|
if (param.getVariables() != null && !param.getVariables().isEmpty()) {
|
|
|
- List<CompanyWorkflowLobsterVariable> insertVars = new ArrayList<>();
|
|
|
- for (CompanyWorkflowLobsterVariable v : param.getVariables()) {
|
|
|
- CompanyWorkflowLobsterVariable entity = new CompanyWorkflowLobsterVariable();
|
|
|
- BeanUtils.copyProperties(v, entity);
|
|
|
- entity.setWorkflowId(templateId);
|
|
|
- entity.setDelFlag(0);
|
|
|
- entity.setUpdateBy(userName);
|
|
|
- entity.setUpdateTime(now);
|
|
|
- if (v.getId() != null) {
|
|
|
- entity.setId(v.getId());
|
|
|
- variableMapper.updateById(entity);
|
|
|
- newVarIds.add(v.getId());
|
|
|
- } else {
|
|
|
- entity.setCreateBy(userName);
|
|
|
- entity.setCreateTime(now);
|
|
|
- insertVars.add(entity);
|
|
|
- }
|
|
|
- }
|
|
|
- if (!insertVars.isEmpty()) {
|
|
|
- variableMapper.batchInsert(insertVars);
|
|
|
- insertVars.forEach(v -> newVarIds.add(v.getId()));
|
|
|
- }
|
|
|
- }
|
|
|
- // 旧的且不在新参数中的变量 → 逻辑删除
|
|
|
- for (CompanyWorkflowLobsterVariable old : oldVariables) {
|
|
|
- if (!newVarIds.contains(old.getId())) {
|
|
|
- variableMapper.deleteById(old.getId());
|
|
|
+ List<CompanyWorkflowLobsterVariable> varEntities = new ArrayList<>();
|
|
|
+ for (CompanyWorkflowLobsterVariableParam it : param.getVariables()) {
|
|
|
+ CompanyWorkflowLobsterVariable v = new CompanyWorkflowLobsterVariable();
|
|
|
+ BeanUtils.copyProperties(it, v);
|
|
|
+ v.setWorkflowId(templateId);
|
|
|
+ v.setDelFlag(0);
|
|
|
+ v.setCreateBy(userName);
|
|
|
+ v.setCreateTime(now);
|
|
|
+ v.setUpdateBy(userName);
|
|
|
+ v.setUpdateTime(now);
|
|
|
+ varEntities.add(v);
|
|
|
}
|
|
|
+ variableMapper.batchInsert(varEntities);
|
|
|
}
|
|
|
|
|
|
- // ==================== 节点:有id更新 / 无id新增 / 旧的且不在新参数中的逻辑删除 ====================
|
|
|
- Set<Long> newNodeIds = new HashSet<>();
|
|
|
+ // 节点:先删后插
|
|
|
+ nodeMapper.deleteByWorkflowId(templateId);
|
|
|
if (param.getNodes() != null && !param.getNodes().isEmpty()) {
|
|
|
- List<CompanyWorkflowLobsterNode> insertNodes = new ArrayList<>();
|
|
|
- for (CompanyWorkflowLobsterNode n : param.getNodes()) {
|
|
|
- CompanyWorkflowLobsterNode entity = new CompanyWorkflowLobsterNode();
|
|
|
- BeanUtils.copyProperties(n, entity);
|
|
|
- entity.setWorkflowId(templateId);
|
|
|
- if (entity.getSortNo() == null) {
|
|
|
- entity.setSortNo(0);
|
|
|
- }
|
|
|
- entity.setDelFlag(0);
|
|
|
- entity.setUpdateBy(userName);
|
|
|
- entity.setUpdateTime(now);
|
|
|
- if (n.getId() != null) {
|
|
|
- entity.setId(n.getId());
|
|
|
- nodeMapper.updateById(entity);
|
|
|
- newNodeIds.add(n.getId());
|
|
|
- } else {
|
|
|
- entity.setCreateBy(userName);
|
|
|
- entity.setCreateTime(now);
|
|
|
- insertNodes.add(entity);
|
|
|
+ List<CompanyWorkflowLobsterNode> nodeEntities = new ArrayList<>();
|
|
|
+ int idx = 0;
|
|
|
+ for (CompanyWorkflowLobsterNodeParam it : param.getNodes()) {
|
|
|
+ CompanyWorkflowLobsterNode n = new CompanyWorkflowLobsterNode();
|
|
|
+ BeanUtils.copyProperties(it, n);
|
|
|
+ n.setWorkflowId(templateId);
|
|
|
+ if (n.getSortNo() == null) {
|
|
|
+ n.setSortNo(idx++);
|
|
|
}
|
|
|
+ n.setDelFlag(0);
|
|
|
+ n.setCreateBy(userName);
|
|
|
+ n.setCreateTime(now);
|
|
|
+ n.setUpdateBy(userName);
|
|
|
+ n.setUpdateTime(now);
|
|
|
+ nodeEntities.add(n);
|
|
|
}
|
|
|
- if (!insertNodes.isEmpty()) {
|
|
|
- nodeMapper.batchInsert(insertNodes);
|
|
|
- insertNodes.forEach(n -> newNodeIds.add(n.getId()));
|
|
|
- }
|
|
|
- }
|
|
|
- // 旧的且不在新参数中的节点 → 逻辑删除
|
|
|
- for (CompanyWorkflowLobsterNode old : oldNodes) {
|
|
|
- if (!newNodeIds.contains(old.getId())) {
|
|
|
- nodeMapper.deleteById(old.getId());
|
|
|
- }
|
|
|
+ nodeMapper.batchInsert(nodeEntities);
|
|
|
}
|
|
|
|
|
|
- // ==================== 连线:有id更新 / 无id新增 / 旧的且不在新参数中的物理删除 ====================
|
|
|
- Set<Long> newEdgeIds = new HashSet<>();
|
|
|
+ // 连线:先删后插(避免 updateById 唯一键冲突陷阱)
|
|
|
+ edgeMapper.deleteByWorkflowId(templateId);
|
|
|
if (param.getEdges() != null && !param.getEdges().isEmpty()) {
|
|
|
- List<CompanyWorkflowLobsterEdge> insertEdges = new ArrayList<>();
|
|
|
- for (CompanyWorkflowLobsterEdge e : param.getEdges()) {
|
|
|
- CompanyWorkflowLobsterEdge entity = new CompanyWorkflowLobsterEdge();
|
|
|
- BeanUtils.copyProperties(e, entity);
|
|
|
- entity.setWorkflowId(templateId);
|
|
|
- if (entity.getSortNo() == null) {
|
|
|
- entity.setSortNo(0);
|
|
|
- }
|
|
|
- entity.setDelFlag(0);
|
|
|
- entity.setUpdateBy(userName);
|
|
|
- entity.setUpdateTime(now);
|
|
|
- if (e.getId() != null) {
|
|
|
- entity.setId(e.getId());
|
|
|
- edgeMapper.updateById(entity);
|
|
|
- newEdgeIds.add(e.getId());
|
|
|
- } else {
|
|
|
- entity.setCreateBy(userName);
|
|
|
- entity.setCreateTime(now);
|
|
|
- insertEdges.add(entity);
|
|
|
+ List<CompanyWorkflowLobsterEdge> edgeEntities = new ArrayList<>();
|
|
|
+ int idx = 0;
|
|
|
+ for (CompanyWorkflowLobsterEdgeParam it : param.getEdges()) {
|
|
|
+ CompanyWorkflowLobsterEdge e = new CompanyWorkflowLobsterEdge();
|
|
|
+ BeanUtils.copyProperties(it, e);
|
|
|
+ e.setWorkflowId(templateId);
|
|
|
+ if (e.getSortNo() == null) {
|
|
|
+ e.setSortNo(idx++);
|
|
|
}
|
|
|
+ e.setDelFlag(0);
|
|
|
+ e.setCreateBy(userName);
|
|
|
+ e.setCreateTime(now);
|
|
|
+ e.setUpdateBy(userName);
|
|
|
+ e.setUpdateTime(now);
|
|
|
+ edgeEntities.add(e);
|
|
|
}
|
|
|
- if (!insertEdges.isEmpty()) {
|
|
|
- edgeMapper.batchInsert(insertEdges);
|
|
|
- insertEdges.forEach(e -> newEdgeIds.add(e.getId()));
|
|
|
- }
|
|
|
- }
|
|
|
- // 旧的且不在新参数中的连线 → 物理删除(避免唯一键冲突)
|
|
|
- for (CompanyWorkflowLobsterEdge old : oldEdges) {
|
|
|
- if (!newEdgeIds.contains(old.getId())) {
|
|
|
- edgeMapper.deleteById(old.getId());
|
|
|
- }
|
|
|
+ edgeMapper.batchInsert(edgeEntities);
|
|
|
}
|
|
|
|
|
|
return AjaxResult.success("画布保存成功");
|