feat: 基本流程crud接口完成

This commit is contained in:
2025-04-26 17:40:29 +08:00
parent 47b8008543
commit 1486b6ad7e
24 changed files with 554 additions and 95 deletions

View File

@@ -74,8 +74,8 @@
<artifactId>lombok-mapstruct-binding</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations-jakarta</artifactId>
</dependency>
</dependencies>

View File

@@ -2,5 +2,5 @@ package com.metis.constant;
public interface BaseConstant {
Integer DEFAULT_VERSION = 0;
Integer DEFAULT_VERSION = 1;
}

View File

@@ -1,12 +1,19 @@
package com.metis.controller;
import com.metis.domain.bo.ProcessBo;
import com.metis.domain.bo.AppBO;
import com.metis.domain.query.AppQuery;
import com.metis.domain.vo.AppVo;
import com.metis.facade.ProcessDefinitionFacade;
import com.metis.domain.entity.App;
import com.metis.result.Result;
import com.metis.result.page.TableDataInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "流程定义")
@RestController
@RequiredArgsConstructor
@RequestMapping("/process/definition")
@@ -15,25 +22,43 @@ public class ProcessDefinitionController {
private final ProcessDefinitionFacade processDefinitionFacade;
@PostMapping("/create")
public Result<Long> create(@RequestBody ProcessBo processBo) {
Long workflowId = processDefinitionFacade.create(processBo);
return Result.ok(workflowId);
}
@PutMapping("/update")
public Result<String> update(@RequestBody ProcessBo processBo) {
processDefinitionFacade.update(processBo);
return Result.ok();
}
@Operation(summary = "根据部署ID获取流程定义")
@GetMapping("/{deploymentId}")
public Result<App> getByDeploymentId(@PathVariable Long deploymentId) {
App app = processDefinitionFacade.getByDeploymentId(deploymentId);
public Result<AppVo> getByDeploymentId(@PathVariable Long deploymentId) {
AppVo app = processDefinitionFacade.getByDeploymentId(deploymentId);
return Result.ok(app);
}
@Operation(summary = "列表查询")
@GetMapping("/list")
public Result<List<AppVo>> list(AppQuery query) {
List<AppVo> table = processDefinitionFacade.list(query);
return Result.ok(table);
}
@Operation(summary = "分页查询")
@GetMapping("/page")
public Result<TableDataInfo<AppVo>> page(AppQuery query) {
TableDataInfo<AppVo> table = processDefinitionFacade.listPage(query);
return Result.ok(table);
}
@Operation(summary = "创建流程定义")
@PostMapping("/create")
public Result<Long> create(@RequestBody AppBO appBO) {
Long workflowId = processDefinitionFacade.create(appBO);
return Result.ok(workflowId);
}
@Operation(summary = "更新流程定义")
@PutMapping("/update")
public Result<Long> update(@RequestBody AppBO appBO) {
Long workflowId = processDefinitionFacade.update(appBO);
return Result.ok(workflowId);
}
@Operation(summary = "删除流程定义")
@DeleteMapping("/{appId}")
public Result<String> delete(@PathVariable Long appId) {
processDefinitionFacade.delete(appId);

View File

@@ -0,0 +1,35 @@
package com.metis.convert;
import com.metis.domain.entity.App;
import com.metis.domain.vo.AppVo;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface AppConvert {
AppConvert INSTANCE = Mappers.getMapper(AppConvert.class);
/**
* 对签证官
*
* @param app 应用程序
* @return {@link AppVo }
*/
AppVo toVo(App app);
/**
* 列举…
*
* @param appList 应用程序列表
* @return {@link List }<{@link AppVo }>
*/
List<AppVo> toListVo(List<App> appList);
}

View File

@@ -25,7 +25,6 @@ public interface BaseAppConvert {
* @return {@link App }
*/
@Mappings({
@Mapping(target = "id", ignore = true),
@Mapping(target = "workflowId", ignore = true),
@Mapping(target = "createTime", ignore = true),
@Mapping(target = "version", ignore = true),
@@ -56,7 +55,6 @@ public interface BaseAppConvert {
@Mapping(target = "createTime", ignore = true),
@Mapping(target = "updateTime", ignore = true),
@Mapping(target = "isDeleted", ignore = true),
@Mapping(target = "id", ignore = true),
@Mapping(target = "createUserId", ignore = true),
@Mapping(target = "defaultUse", ignore = true)
})
@@ -88,9 +86,6 @@ public interface BaseAppConvert {
* @param updateApp 更新应用程序
* @return {@link BuildApp }
*/
@Mappings({
@Mapping(target = "userId", ignore = true)
})
BuildApp toBuildApp(UpdateApp updateApp);
}

View File

@@ -12,6 +12,12 @@ public interface GraphConvert {
GraphConvert INSTANCE = Mappers.getMapper(GraphConvert.class);
/**
* 实体
*
* @param graph 图
* @return {@link Graph }
*/
Graph toEntity(GraphBO graph);
}

View File

@@ -1,11 +1,10 @@
package com.metis.domain.bo;
import com.metis.enums.YesOrNoEnum;
import com.metis.domain.bo.GraphBO;
import lombok.Data;
@Data
public class ProcessBo {
public class AppBO {
private Long appId;

View File

@@ -13,7 +13,7 @@ public class App {
/**
* 主键
*/
private Long id;
private Long appId;
/**
* 部署id

View File

@@ -0,0 +1,60 @@
package com.metis.domain.vo;
import com.metis.enums.YesOrNoEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Schema(description = "应用")
public class AppVo {
/**
* 主键
*/
@Schema(description = "appId, 应用id")
private Long appId;
/**
* 部署id
*/
@Schema(description = "部署id")
private Long workflowId;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 描述
*/
@Schema(description = "描述")
private String description;
/**
* 图
*/
@Schema(description = "")
private GraphVo graph;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 版本
*/
@Schema(description = "版本")
private Integer version;
/**
* 默认使用
*/
@Schema(description = "默认使用")
private YesOrNoEnum defaultUse;
}

View File

@@ -0,0 +1,70 @@
package com.metis.domain.vo;
import com.metis.enums.EdgeType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "连线")
public class EdgeVo {
/**
* 唯一标识符
*/
@Schema(description = "唯一标识符")
private String id;
/**
* 标签
*/
@Schema(description = "标签")
private String label;
/**
* 节点类型
*/
@Schema(description = "节点类型")
private EdgeType type;
/**
* 源节点ID,对应节点id
*/
@Schema(description = "源节点ID,对应节点id")
private Long source;
/**
* 目标节点ID,对应节点id
*/
@Schema(description = "目标节点ID,对应节点id")
private Long target;
/**
* 源句柄id
*/
@Schema(description = "源句柄id")
private Long sourceHandle;
/**
* 目标句柄id
*/
@Schema(description = "目标句柄id")
private Long targetHandle;
/**
* 边是否动画true/false
*/
@Schema(description = "边是否动画true/false")
private Boolean animated;
/**
* 开始标志
*/
@Schema(description = "开始标志")
private String markerStart;
/**
* 结束标记
*/
@Schema(description = "结束标记")
private String markerEnd;
}

View File

@@ -0,0 +1,44 @@
package com.metis.domain.vo;
import com.metis.domain.entity.base.Viewport;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class GraphVo {
/**
* 边缘
*/
@Schema(description = "边缘")
private List<EdgeVo> edges;
/**
* 节点
*/
@Schema(description = "节点")
private List<NodeVo> nodes;
/**
* 位置
*/
@Schema(description = "位置")
private List<Double> position;
/**
* 变焦
*/
@Schema(description = "变焦")
private Double zoom;
/**
* 视窗
*/
@Schema(description = "视窗")
private Viewport viewport;
}

View File

@@ -0,0 +1,34 @@
package com.metis.domain.vo;
import com.metis.enums.HandleType;
import com.metis.enums.PositionType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "句柄")
public class HandleVo {
/**
* 句柄id
*/
@Schema(description = "句柄id")
private Long id;
/**
* 句柄类型
*/
@Schema(description = "句柄类型")
private HandleType type;
/**
* 句柄位置
*/
@Schema(description = "句柄位置")
private PositionType position;
/**
* 是否可以连接
*/
@Schema(description = "是否可以连接")
private Boolean connectable;
}

View File

@@ -0,0 +1,45 @@
package com.metis.domain.vo;
import com.alibaba.fastjson2.JSONObject;
import com.metis.enums.PositionType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "节点业务数据")
public class NodeDataVo {
/**
* 标签
*/
@Schema(description = "标签")
private String label;
/**
* 图标
*/
@Schema(description = "图标")
private String icon;
/**
* 工具栏位置
*/
@Schema(description = "工具栏位置")
private PositionType toolbarPosition;
/**
* 配置
*/
@Schema(description = "配置")
private JSONObject config;
/**
* 句柄列表
*/
@Schema(description = "句柄列表")
private List<HandleVo> handles;
}

View File

@@ -0,0 +1,55 @@
package com.metis.domain.vo;
import com.metis.enums.NodeType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class NodeVo {
/**
* id
*/
@Schema(description = "节点id")
private Long id;
/**
* 类型
*/
@Schema(description = "节点类型")
private NodeType type;
@Schema(description = "自定义类型")
private String customType;
/**
* 位置
*/
@Schema(description = "节点位置")
private PositionVo position;
/**
* 业务数据
*/
@Schema(description = "节点业务数据")
private NodeDataVo data;
/**
* 宽度
*/
@Schema(description = "节点宽度")
private Integer width;
/**
* 高度
*/
@Schema(description = "节点高度")
private Integer height;
/**
* 节点是否选中
*/
@Schema(description = "节点是否选中")
private Boolean selected;
}

View File

@@ -0,0 +1,20 @@
package com.metis.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "位置")
public class PositionVo {
/**
* x坐标
*/
@Schema(description = "x坐标")
private Double x;
/**
* y坐标
*/
@Schema(description = "y坐标")
private Double y;
}

View File

@@ -5,6 +5,7 @@ import com.metis.domain.bo.CreateApp;
import com.metis.domain.bo.UpdateApp;
import com.metis.domain.entity.App;
import com.metis.domain.query.AppQuery;
import com.metis.result.page.TableDataInfo;
import java.util.List;
@@ -16,7 +17,7 @@ public interface AppEngineService {
* @param query 查询
* @return {@link List }<{@link App }>
*/
List<App> listPage(AppQuery query);
TableDataInfo<App> listPage(AppQuery query);
/**
* 列表
@@ -30,10 +31,11 @@ public interface AppEngineService {
/**
* 通过应用id获取
*
* @param appId 应用程序id
* @param appId 应用程序id
* @param defaultUse 默认使用
* @return {@link App }
*/
App getByAppId(Long appId);
App getByAppId(Long appId, boolean defaultUse);
/**
* 按身份证领取

View File

@@ -3,6 +3,7 @@ package com.metis.engine.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.metis.constant.BaseConstant;
import com.metis.convert.BaseAppConvert;
import com.metis.domain.bo.BuildApp;
@@ -13,7 +14,9 @@ import com.metis.domain.entity.BaseApp;
import com.metis.domain.query.AppQuery;
import com.metis.engine.AppEngineService;
import com.metis.enums.YesOrNoEnum;
import com.metis.result.page.TableDataInfo;
import com.metis.service.BaseAppService;
import com.metis.utils.PageConditionUtil;
import com.metis.validator.ValidatorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -32,9 +35,9 @@ public class AppEngineServiceImpl implements AppEngineService {
@Override
public List<App> listPage(AppQuery query) {
List<BaseApp> list = baseAppService.listPage(query);
return BaseAppConvert.INSTANCE.toApps(list);
public TableDataInfo<App> listPage(AppQuery query) {
IPage<BaseApp> page = baseAppService.listPage(query);
return PageConditionUtil.convertDataTable(page, BaseAppConvert.INSTANCE::toApp);
}
@Override
@@ -44,8 +47,13 @@ public class AppEngineServiceImpl implements AppEngineService {
}
@Override
public App getByAppId(Long appId) {
BaseApp baseApp = baseAppService.getByAppId(appId);
public App getByAppId(Long appId, boolean defaultUse) {
BaseApp baseApp;
if (defaultUse) {
baseApp = baseAppService.getDefaultByAppId(appId);
} else {
baseApp = baseAppService.getLastByAppId(appId);
}
return BaseAppConvert.INSTANCE.toApp(baseApp);
}
@@ -84,7 +92,7 @@ public class AppEngineServiceImpl implements AppEngineService {
@Override
@Transactional(rollbackFor = Exception.class)
public synchronized App update(UpdateApp updateApp) {
BaseApp entity = baseAppService.getByAppId(updateApp.getAppId());
BaseApp entity = baseAppService.getLastByAppId(updateApp.getAppId());
Assert.isTrue(ObjectUtil.isNotNull(entity), "app不存在");
BuildApp buildApp = BaseAppConvert.INSTANCE.toBuildApp(updateApp);
// 校验
@@ -119,7 +127,7 @@ public class AppEngineServiceImpl implements AppEngineService {
*/
private App creatApp(BaseApp baseApp, BuildApp buildApp) {
App app = BaseAppConvert.INSTANCE.toApp(buildApp);
app.setId(baseApp.getId());
app.setAppId(baseApp.getId());
app.setWorkflowId(baseApp.getId());
app.setDefaultUse(baseApp.getDefaultUse());
return app;

View File

@@ -45,7 +45,7 @@ public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerServic
// 构建系统上下文信息
SysContext sysContext = SysContext.builder()
.files(context.getFiles())
.appId(app.getId())
.appId(app.getAppId())
.workflowId(app.getWorkflowId())
.instanceId(instanceId)
.build();
@@ -100,34 +100,6 @@ public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerServic
}
private void doRunning(Set<Node> readyRunningNode, Map<Long, List<Edge>> edgeMap, RunningContext runningContext) {
Set<Long> nextRunningNodeId = new HashSet<>();
for (Node runningNode : readyRunningNode) {
// 当前节点接下来的连接线信息
List<Edge> edges = edgeMap.getOrDefault(runningNode.getId(), new ArrayList<>());
// 执行
NodeRunner nodeRunner = getNodeRunner(runningNode);
runningNode.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner));
// 获取到返回结果
RunningResult result = nodeRunner.run(runningContext, runningNode, edges);
// 节点执行结果参数放入上下文中
if (ObjectUtil.isNotNull(result.getNodeContext())) {
runningContext.addNodeRunningContext(runningNode.getId(), result.getNodeContext());
}
if (CollUtil.isNotEmpty(result.getNextRunNodeId())) {
nextRunningNodeId.addAll(result.getNextRunNodeId());
}
}
}
private RunningResult doRunning(RunningContext runningContext, Node node, List<Edge> edges) {
NodeRunner nodeRunner = getNodeRunner(node);
node.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner));
// 获取到返回结果
return nodeRunner.run(runningContext, node, edges);
}
/**
* 获取节点运行程序
@@ -154,6 +126,6 @@ public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerServic
if (ObjectUtil.isNotNull(context.getWorkflowId())) {
return appEngineService.getByWorkflowId(context.getWorkflowId());
}
return appEngineService.getByAppId(context.getAppId());
return appEngineService.getByAppId(context.getAppId(), true);
}
}

View File

@@ -1,15 +1,22 @@
package com.metis.facade;
import com.metis.convert.AppConvert;
import com.metis.convert.GraphConvert;
import com.metis.domain.bo.CreateApp;
import com.metis.domain.bo.ProcessBo;
import com.metis.domain.bo.AppBO;
import com.metis.domain.bo.UpdateApp;
import com.metis.domain.entity.App;
import com.metis.domain.entity.base.Graph;
import com.metis.domain.query.AppQuery;
import com.metis.domain.vo.AppVo;
import com.metis.engine.AppEngineService;
import com.metis.result.page.TableDataInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j
@Service
@@ -18,36 +25,80 @@ public class ProcessDefinitionFacade {
private final AppEngineService appEngineService;
/**
* 通过部署id获取
*
* @param deploymentId 部署id
* @return {@link App }
*/
public AppVo getByDeploymentId(Long deploymentId) {
App app = appEngineService.getByWorkflowId(deploymentId);
return AppConvert.INSTANCE.toVo(app);
}
/**
* 列表
*
* @param query 查询
* @return {@link TableDataInfo }<{@link AppVo }>
*/
public List<AppVo> list(AppQuery query) {
List<App> list = appEngineService.list(query);
return AppConvert.INSTANCE.toListVo(list);
}
/**
* 列表页面
*
* @param query 查询
* @return {@link TableDataInfo }<{@link AppVo }>
*/
public TableDataInfo<AppVo> listPage(AppQuery query) {
TableDataInfo<App> dataInfo = appEngineService.listPage(query);
return dataInfo.convertDataTable(AppConvert.INSTANCE::toVo);
}
/**
* 创建
*
* @param processBo 过程业务对象
* @param appBO 过程业务对象
*/
public Long create(ProcessBo processBo) {
Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph());
@Transactional(rollbackFor = Exception.class)
public Long create(AppBO appBO) {
Graph graph = GraphConvert.INSTANCE.toEntity(appBO.getGraph());
CreateApp createApp = CreateApp.builder()
.name(processBo.getName())
.name(appBO.getName())
.graph(graph)
.build();
App app = appEngineService.create(createApp);
return app.getWorkflowId();
}
public App getByDeploymentId(Long deploymentId) {
return appEngineService.getByWorkflowId(deploymentId);
}
public void update(ProcessBo processBo) {
Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph());
appEngineService.update(UpdateApp.builder()
.defaultUse(processBo.getDefaultUse())
.appId(processBo.getAppId())
.name(processBo.getName())
/**
* 更新
*
* @param appBO 过程业务对象
*/
@Transactional(rollbackFor = Exception.class)
public Long update(AppBO appBO) {
Graph graph = GraphConvert.INSTANCE.toEntity(appBO.getGraph());
App update = appEngineService.update(UpdateApp.builder()
.defaultUse(appBO.getDefaultUse())
.appId(appBO.getAppId())
.name(appBO.getName())
.graph(graph)
.build());
return update.getWorkflowId();
}
/**
* 删除
*
* @param appId 应用程序id
*/
@Transactional(rollbackFor = Exception.class)
public void delete(Long appId) {
appEngineService.delete(appId);
}

View File

@@ -1,10 +1,12 @@
package com.metis.result.page;
import cn.hutool.core.collection.CollUtil;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.function.Function;
/**
* 表格分页数据对象
@@ -42,4 +44,14 @@ public class TableDataInfo<T> implements Serializable {
this.total = total;
}
public <V> TableDataInfo<V> convertDataTable(Function<T, V> function) {
TableDataInfo<V> tableDataInfo = new TableDataInfo<>();
if (CollUtil.isNotEmpty(this.rows)) {
tableDataInfo.setRows(this.rows.stream().map(function).toList());
}
tableDataInfo.setTotal(this.total);
return tableDataInfo;
}
}

View File

@@ -1,5 +1,6 @@
package com.metis.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.metis.enums.YesOrNoEnum;
import com.metis.domain.query.AppQuery;
import com.metis.domain.entity.BaseApp;
@@ -16,19 +17,27 @@ import java.util.List;
public interface BaseAppService extends IService<BaseApp> {
/**
* 获取默认当前使用
*
* @param appId 应用程序id
* @return {@link BaseApp }
*/
BaseApp getDefaultByAppId(Long appId);
/**
* 通过应用id获取
*
* @param appId 应用程序id
* @return {@link BaseApp }
*/
BaseApp getByAppId(Long appId);
BaseApp getLastByAppId(Long appId);
/**
* 通过id和版本获取
*
* @param appId id
* @param appId id
* @param version 版本
* @return {@link BaseApp }
*/
@@ -40,7 +49,7 @@ public interface BaseAppService extends IService<BaseApp> {
* @param query 查询
* @return {@link List }<{@link BaseApp }>
*/
List<BaseApp> listPage(AppQuery query);
IPage<BaseApp> listPage(AppQuery query);
/**
* 列表查询

View File

@@ -25,8 +25,18 @@ import java.util.List;
public class BaseAppServiceImpl extends ServiceImpl<BaseAppMapper, BaseApp>
implements BaseAppService {
@Override
public BaseApp getByAppId(Long appId) {
public BaseApp getDefaultByAppId(Long appId) {
return this.lambdaQuery()
.eq(BaseApp::getAppId, appId)
.eq(BaseApp::getDefaultUse, YesOrNoEnum.YES)
.last("limit 1")
.one();
}
@Override
public BaseApp getLastByAppId(Long appId) {
return this.lambdaQuery()
.eq(BaseApp::getAppId, appId)
.orderByDesc(BaseApp::getVersion)
@@ -45,10 +55,10 @@ public class BaseAppServiceImpl extends ServiceImpl<BaseAppMapper, BaseApp>
}
@Override
public List<BaseApp> listPage(AppQuery query) {
public IPage<BaseApp> listPage(AppQuery query) {
IPage<BaseApp> page = PageConditionUtil.getPage();
LambdaQueryWrapper<BaseApp> wrapper = buildQuery(query);
return baseMapper.selectList(page, wrapper);
return baseMapper.selectPage(page, wrapper);
}
@@ -92,9 +102,10 @@ public class BaseAppServiceImpl extends ServiceImpl<BaseAppMapper, BaseApp>
LambdaQueryWrapper<BaseApp> wrapper = new LambdaQueryWrapper<>();
wrapper.select(BaseApp::getId, BaseApp::getAppId, BaseApp::getName,
BaseApp::getDescription, BaseApp::getVersion, BaseApp::getIsDeleted,
BaseApp::getCreateTime, BaseApp::getUpdateTime)
BaseApp::getCreateTime, BaseApp::getUpdateTime, BaseApp::getDefaultUse)
.like(StrUtil.isNotBlank(query.getName()), BaseApp::getName, query.getName())
.like(StrUtil.isNotBlank(query.getDescription()), BaseApp::getDescription, query.getDescription());
.like(StrUtil.isNotBlank(query.getDescription()), BaseApp::getDescription, query.getDescription())
.orderByDesc(BaseApp::getCreateTime);
if (ObjectUtil.isNotNull(query.getAppId())) {
wrapper.eq(BaseApp::getAppId, query.getAppId());
} else {