add:流程编排

This commit is contained in:
zhangzq
2024-03-25 15:55:45 +08:00
parent 3175199b65
commit a3b91e18e4
56 changed files with 1573 additions and 1 deletions

View File

@@ -59,7 +59,7 @@ public class CodeGenerator {
dsc.setUrl("jdbc:mysql://localhost:3306/wms?serverTimezone=GMT&setUnicode=true&characterEncoding=utf8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("password");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();

View File

@@ -0,0 +1,20 @@
# wms
表结构
####act_de_model
CREATE TABLE `act_de_model` (
`id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '主键id',
`name` varchar(1298) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '模型名称',
`model_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'key',
`description` varchar(4000) COMMENT '模型描述',
`model_comment` varchar(4000) DEFAULT NULL COMMENT '模型注释',
`create_time` varchar(25) DEFAULT NULL COMMENT '创建时间',
`create_id` varchar(20) DEFAULT NULL COMMENT '创建人',
`update_time` varchar(25) DEFAULT NULL COMMENT '修改时间',
`updated_id` varchar(20) COMMENT '修改人',
`version` int DEFAULT NULL COMMENT '版本号',
`model_editor_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT '模型json数据',
`thumbnail` longblob COMMENT '模型封面',
`model_type` int DEFAULT NULL COMMENT '模型类型',
`tenant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '归属租户',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='模型表'

View File

@@ -0,0 +1,32 @@
package org.nl.wms.flow_manage.flow.controller.execution;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import org.nl.wms.flow_manage.flow.service.execution.IFlowOperationService;
import org.nl.wms.flow_manage.flow.service.execution.dto.StartProcessInstanceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.File;
/*
* @author ZZQ
* @Date 2024/3/19 16:27
*/
@RestController
@RequestMapping("/api/bpmnExecution")
@SaIgnore
public class ExecutionController {
@Autowired
IFlowOperationService flowOperationService;
@PostMapping(value = "/open")
public ResponseEntity<Object> getBpmnByModelId(JSONObject form){
StartProcessInstanceVo startProcessInstanceVo = form.toJavaObject(StartProcessInstanceVo.class);
return new ResponseEntity<>(flowOperationService.startFormFlow(startProcessInstanceVo), HttpStatus.OK);
}
}

View File

@@ -0,0 +1,72 @@
package org.nl.wms.flow_manage.flow.controller.model;
import cn.dev33.satoken.annotation.SaIgnore;
import org.nl.common.utils.FileUtil;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.impl.StartInstanceCmd;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.service.deployment.IActReProcdefService;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
import org.nl.wms.flow_manage.flow.service.model.IActDeModelService;
import org.nl.wms.flow_manage.flow.service.model.dao.ActDeModel;
import org.nl.wms.flow_manage.flow.service.model.dto.ModelInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.FileInputStream;
/**
* <p>
* 模型表 前端控制器
* </p>
*
* @author generator
* @since 2024-03-18
*/
@RestController
@RequestMapping("api/flow/bpmnDesigner")
@SaIgnore
public class ActDeModelController {
@Autowired
IActDeModelService modelService;
@Autowired
IActReProcdefService reProcdefService;
@Autowired
CommandExecutor commandExecutor;
@GetMapping(value = "/select/{modelId}", produces = "application/json")
public ResponseEntity<ModelInfoVo> getBpmnByModelId(@PathVariable String modelId){
ActDeModel byId = modelService.getById(modelId);
ModelInfoVo vo = new ModelInfoVo();
vo.setModelId(byId.getId());
vo.setModelKey(byId.getModel_key());
vo.setModelName(byId.getName());
vo.setFileName(byId.getName());
File file = new File("/Users/mima0000/Desktop/model");
String s = FileUtil.readString(file, "utf-8");
vo.setModelXml(s);
vo.setAppSn(byId.getTenant_id());
return new ResponseEntity<>(vo, HttpStatus.OK);
}
@GetMapping(value = "/start/{deployment_id}", produces = "application/json")
public ResponseEntity<ModelInfoVo> startByModelId(@PathVariable String deployment_id){
ActReProcdef deployment = reProcdefService.getById(deployment_id);
String model_editor_json = deployment.getModel_editor_json();
//TODO:转成bpmnModel对象:创建ExecutionEntity参数
ExecutionEntity entity = new ExecutionEntity();
commandExecutor.execute(new StartInstanceCmd(),new ExecutionEntity());
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,33 @@
package org.nl.wms.flow_manage.flow.framework.config;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.CommandInterceptor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.impl.InvokeCommandInterceptor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.impl.ThreadCommandInterceptor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/*
* @author ZZQ
* @Date 2024/3/21 11:26
*/
public class InitFlowConfig {
public void initConfig(){
CommandInterceptor first = initCommandInterceptor();
CommandExecutor commandExecutor = new CommandExecutor();
commandExecutor.setInterceptor(first);
}
public CommandInterceptor initCommandInterceptor(){
List<CommandInterceptor> chain = new ArrayList<>();
chain.add(new ThreadCommandInterceptor());
chain.add(new InvokeCommandInterceptor());
for (int i = 0; i < chain.size() - 1; i++) {
chain.get(i).setNext(chain.get(i + 1));
}
return chain.get(0);
}
}

View File

@@ -0,0 +1,28 @@
package org.nl.wms.flow_manage.flow.framework.engine.agenda;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import java.util.LinkedList;
/*
* @author ZZQ
* @Date 2024/3/21 10:33
* 迭代器模式统一处理operation:多线程并行处理跟顺序处理两种
* //线程安全的一个线程维护一个,
*/
public class FlowableEngineAgenda {
private LinkedList<Runnable> operations = new LinkedList<>();
public FlowableEngineAgenda planOperation(Runnable runnable){
operations.add(runnable);
return this;
}
public void execute(){
while (!operations.isEmpty()){
Runnable poll = operations.poll();
poll.run();
}
}
}

View File

@@ -0,0 +1,23 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/18 11:08
* sql如果要考虑事务的话可以考虑将sql放入一个地方最后一起执行
*/
public abstract class FlowNodeActivityBehavior<T> {
public void execute(ExecutionEntity<T> execution) {
leave(execution);
}
/**
* Default way of leaving a BPMN 2.0 activity: evaluate the conditions on the outgoing sequence flow and take those that evaluate to true.
*/
public void leave(ExecutionEntity<T> execution) {
leave(execution);
}
}

View File

@@ -0,0 +1,36 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.task.impl.FormTask;
import org.springframework.stereotype.Service;
/*
* @author ZZQ
* @Date 2024/3/18 13:17
* 源UserTask
*/
@Service
public class FormTaskActivityBehavior extends FlowNodeActivityBehavior<FlowNode> {
@Override
public void execute(ExecutionEntity<FlowNode> execution) {
FlowElement flowElement = execution.getCurrentFlowElement();
String type = flowElement.getType();
if (flowElement instanceof FormTask){
//根据当前表单配置生成当前节点表单数据
FormTask formTask = (FormTask) flowElement;
}
//TODO:获取不同的类型执行器.处理该节点:获取当前表单
//获取表单配置表
super.execute(execution);
super.execute(execution);
}
@Override
public void leave(ExecutionEntity execution) {
super.leave(execution);
}
}

View File

@@ -0,0 +1,12 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.springframework.stereotype.Service;
/*
* @author ZZQ
* @Date 2024/3/18 13:17
*/
@Service
public class GateWayActivityBehavior extends FlowNodeActivityBehavior {
}

View File

@@ -0,0 +1,12 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.springframework.stereotype.Service;
/*
* @author ZZQ
* @Date 2024/3/18 13:17
*/
@Service
public class ScriptTaskActivityBehavior extends FlowNodeActivityBehavior {
}

View File

@@ -0,0 +1,12 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.springframework.stereotype.Service;
/*
* @author ZZQ
* @Date 2024/3/18 13:17
*/
@Service
public class ServerTaskActivityBehavior extends FlowNodeActivityBehavior {
}

View File

@@ -0,0 +1,61 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.utils.IdUtil;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.operation.impl.ContinuOperation;
import org.nl.wms.flow_manage.flow.framework.engine.operation.impl.SequenceFlowOperation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.Sequen.SequenceFlow;
import org.nl.wms.flow_manage.flow.service.deployment.IActReProcdefService;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
import org.nl.wms.flow_manage.flow.service.execution.IActRuExecutionService;
import org.nl.wms.flow_manage.flow.service.execution.dao.ActRuExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/*
* @author ZZQ
* @Date 2024/3/18 13:17
* 源UserTask
*/
@Service
public class StartEventActivityBehavior extends FlowNodeActivityBehavior {
@Autowired
IActRuExecutionService executionService;
@Autowired
IActReProcdefService deploymentService;
@Override
public void execute(ExecutionEntity execution) {
FlowNode flowNode = (FlowNode)execution.getCurrentFlowElement();
String type = flowNode.getType();
/*
* 1.创建实例对象
* 2.创建当前activity_id
* 3.保存当前表单信息
* 4.跳转到下一个流程FormTask
* 5.离开节点的时进行squeaflow表达式判断
* */
ActReProcdef deployment = deploymentService.getById(execution.getDeploymentId());
if (deployment==null){throw new BadRequestException("当前部署的流程状态异常");}
ActRuExecution actRuExecution = new ActRuExecution();
actRuExecution.setActivity_id(execution.getActivityId());
actRuExecution.setDeployment_id(deployment.getDeployment_id());
actRuExecution.setProc_inst_id(IdUtil.getStringId());
executionService.save(actRuExecution);
this.leave(execution);
}
@Override
public void leave(ExecutionEntity execution) {
CommandExecutor.getAgenda().planOperation(new SequenceFlowOperation(execution));
}
}

View File

@@ -0,0 +1,38 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.engine.agenda.FlowableEngineAgenda;
import org.nl.wms.flow_manage.flow.framework.engine.behavior.FlowNodeActivityBehavior;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.CommandInterceptor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/*
* @author ZZQ
* @Date 2024/3/21 11:14
*/
@Service
public class CommandExecutor {
//线程变量
public static ThreadLocal<FlowableEngineAgenda> agenda = new ThreadLocal();
//不同类型处理器
public static Map<String, FlowNodeActivityBehavior> activityBehaviorMap = new HashMap<>();
//指令拦截器链
private CommandInterceptor first;
public void execute(Command command, ExecutionEntity entity){
first.chainExecute(command,entity);
}
public static FlowableEngineAgenda getAgenda(){
return agenda.get();
}
public void setInterceptor(CommandInterceptor first){
this.first =first;
}
}

View File

@@ -0,0 +1,34 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor;
import lombok.Data;
import org.apache.poi.ss.formula.functions.T;
import org.nl.wms.flow_manage.flow.framework.config.InitFlowConfig;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/21 11:10
* 链式调用
*/
@Data
public abstract class CommandInterceptor {
private CommandInterceptor next;
protected abstract <T> T execute(Command<T> command, ExecutionEntity entity);
protected abstract <T> T leave(Command<T> command, ExecutionEntity entity);
public void chainExecute(Command<T> command, ExecutionEntity entity){
try {
this.execute(command,entity);
if (this.next!=null){
this.next.chainExecute(command,entity);
}
}finally {
this.leave(command,entity);
}
}
}

View File

@@ -0,0 +1,28 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.impl;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.CommandInterceptor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/21 11:11
*/
public class InvokeCommandInterceptor extends CommandInterceptor {
@Override
protected <T> T execute(Command<T> command, ExecutionEntity entity) {
System.out.println("执行Invoke开始方法");
command.execute(entity);
return null;
}
@Override
protected <T> T leave(Command<T> command, ExecutionEntity entity) {
//统一执行
CommandExecutor.getAgenda().execute();
//更新当前流程实例表节点信息
System.out.println("执行Invoke结束方法");
return null;
}
}

View File

@@ -0,0 +1,31 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.impl;
import org.nl.wms.flow_manage.flow.framework.engine.agenda.FlowableEngineAgenda;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.interceptor.CommandInterceptor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/21 11:11
*/
public class ThreadCommandInterceptor extends CommandInterceptor {
@Override
protected <T> T execute(Command<T> command, ExecutionEntity entity) {
System.out.println("执行Thread开始方法");
ThreadLocal<FlowableEngineAgenda> agenda = CommandExecutor.agenda;
FlowableEngineAgenda flowableEngineAgenda = agenda.get();
if (flowableEngineAgenda==null){
agenda.set(new FlowableEngineAgenda());
}
return null;
}
@Override
protected <T> T leave(Command<T> command, ExecutionEntity entity) {
CommandExecutor.agenda.remove();
System.out.println("执行Thread结束方法");
return null;
}
}

View File

@@ -0,0 +1,14 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.unify;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.formula.functions.T;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/19 17:56
*/
public interface Command<T> {
T execute(ExecutionEntity commandContext);
}

View File

@@ -0,0 +1,21 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.impl;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.engine.operation.impl.ContinuOperation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
/*
* @author ZZQ
* @Date 2024/3/19 17:57
*/
public class StartInstanceCmd implements Command {
@Override
public Object execute(ExecutionEntity entity) {
//获取当前流程版本信息:
FlowElement currentFlowElement = entity.getCurrentFlowElement();
CommandExecutor.getAgenda().planOperation(new ContinuOperation(entity));
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.nl.wms.flow_manage.flow.framework.engine.operation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/21 10:13
*/
public class AbstractOperation implements Runnable{
public ExecutionEntity execution;
@Override
public void run() {
}
}

View File

@@ -0,0 +1,43 @@
package org.nl.wms.flow_manage.flow.framework.engine.operation.impl;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.operation.AbstractOperation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.Sequen.SequenceFlow;
/*
* @author ZZQ
* @Date 2024/3/21 10:14
* 节点流转:
* 如果是flowNode节点则调用behavior执行节点处理
*如果是squeaFlow则继续创建ContinuOperation直到找到flowNode节点
*/
public class ContinuOperation extends AbstractOperation {
public ContinuOperation(ExecutionEntity execution) {
this.execution=execution;
}
@Override
public void run() {
FlowElement currentFlowElement = execution.getCurrentFlowElement();
//插入流程历史表act_hi_procinst起点流程id->终点流程id,当前流程参数等
if (currentFlowElement instanceof FlowNode) {
//TODO:执行监听器
//处理当前节点业务更新当前流程执行id获取当前流程节点对应的处理器
CommandExecutor.activityBehaviorMap.get(currentFlowElement.getType()).execute(execution);
// continueThroughFlowNode((FlowNode) currentFlowElement);
} else if (currentFlowElement instanceof SequenceFlow) {
SequenceFlow sequenceFlow = (SequenceFlow) currentFlowElement;
//判断当前流程表达式是否中断或者跳过:跳过则执行下一个流程
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
execution.setCurrentFlowElement(targetFlowElement);
CommandExecutor.getAgenda().planOperation(new ContinuOperation(execution));
} else {
throw new BadRequestException("当前流程类型为定义:"+currentFlowElement.getClass().getName());
}
}
}

View File

@@ -0,0 +1,38 @@
package org.nl.wms.flow_manage.flow.framework.engine.operation.impl;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.operation.AbstractOperation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.Sequen.SequenceFlow;
import java.util.List;
/*
* @author ZZQ
* @Date 2024/3/21 10:14
* 节点跳转
*/
public class SequenceFlowOperation extends AbstractOperation {
public SequenceFlowOperation(ExecutionEntity entity) {
this.execution=entity;
}
@Override
public void run() {
FlowElement flowElement = execution.getCurrentFlowElement();
if (flowElement instanceof FlowNode){
FlowNode flowNode = (FlowNode) flowElement;
List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
for (SequenceFlow sequenceFlow : outgoingFlows) {
String skipExpression = sequenceFlow.getSkipExpression();
//流程线的脚本判断获取当下一个节点
execution.setCurrentFlowElement(sequenceFlow.getTargetFlowElement());
}
//
CommandExecutor.getAgenda().planOperation(new ContinuOperation(execution));
}
}
}

View File

@@ -0,0 +1,31 @@
package org.nl.wms.flow_manage.flow.framework.entity;
import lombok.Data;
import lombok.Getter;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
/*
* @author ZZQ
* @Date 2024/3/18 13:15
* 流程执行相关参数
*/
@Getter
public class ExecutionEntity<T> {
protected FlowElement currentFlowElement;
//用于获取当前流程实例对象
protected String processDefinitionId;
//当前流程id=currentFlowElement.getId()
protected String startActivityId;
protected String activityId;
protected String deploymentId;
protected T t;
public void setCurrentFlowElement(FlowElement currentFlowElement) {
this.currentFlowElement = currentFlowElement;
this.activityId = currentFlowElement.getId();
}
public void setT(T t) {
this.t = t;
}
}

View File

@@ -0,0 +1,22 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.base;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.ExtensionElement;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/*
* @author ZZQ
* @Date 2024/3/18 11:13
*/
@Data
public class BaseElement {
protected String id;
protected int xmlRowNumber;
protected int xmlColumnNumber;
protected Map<String, List<ExtensionElement>> extensionElements = new LinkedHashMap<>();
/** extension attributes could be part of each element */
protected Map<String, List<ExtensionAttribute>> attributes = new LinkedHashMap<>();
}

View File

@@ -0,0 +1,25 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.wms.flow_manage.flow.framework.entity.node.base;
import lombok.Data;
@Data
public class ExtensionAttribute {
protected String name;
protected String value;
protected String namespacePrefix;
protected String namespace;
}

View File

@@ -0,0 +1,21 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.base.impl;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.BaseElement;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/*
* @author ZZQ
* @Date 2024/3/18 11:18
*/
@Data
public class ExtensionElement extends BaseElement {
protected String name;
protected String namespacePrefix;
protected String namespace;
protected String elementText;
protected Map<String, List<ExtensionElement>> childElements = new LinkedHashMap<>();
}

View File

@@ -0,0 +1,31 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.wms.flow_manage.flow.framework.entity.node.base.impl;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.BaseElement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Data
public abstract class FlowElement extends BaseElement {
protected String type;
protected String name;
protected String documentation;
protected List<Map> executionListeners = new ArrayList<>();
// protected FlowElementsContainer parentContainer;
}

View File

@@ -0,0 +1,26 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.base.impl;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.Sequen.SequenceFlow;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/*
* @author ZZQ
* @Date 2024/3/18 11:22
*/
@Data
public abstract class FlowNode extends FlowElement {
private String name;
private String documentation;
//监听器配置暂时不需要
private List<Map> executionListeners = new ArrayList<>();
private boolean asynchronous;
private boolean asynchronousLeave;
private boolean notExclusive;
private List<SequenceFlow> incomingFlows = new ArrayList<>();
private List<SequenceFlow> outgoingFlows = new ArrayList<>();
}

View File

@@ -0,0 +1,39 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.wms.flow_manage.flow.framework.entity.node.impl.Sequen;
import lombok.Data;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowElement;
import java.util.ArrayList;
import java.util.List;
@Data
public class SequenceFlow extends FlowElement {
protected String conditionExpression;
protected String skipExpression;
protected FlowElement sourceFlowElement;
protected FlowElement targetFlowElement;
/**
* Graphical information: a list of waypoints: x1, y1, x2, y2, x3, y3, ..
*
* Added during parsing of a process definition.
*/
protected List<Integer> waypoints = new ArrayList<>();
}

View File

@@ -0,0 +1,35 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.impl.gateway;
import org.apache.poi.hpsf.CustomProperty;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import java.util.*;
/*
* @author ZZQ
* @Date 2024/3/18 11:30
* 源UserTask
*/
public class GateWay extends FlowNode {
protected String assignee;
protected String owner;
protected String priority;
protected String formKey;
protected boolean sameDeployment = true;
protected String dueDate;
protected String businessCalendarName;
protected String category;
protected String extensionId;
protected List<String> candidateUsers = new ArrayList<>();
protected List<String> candidateGroups = new ArrayList<>();
// protected List<FormProperty> formProperties = new ArrayList<>();
// protected List<FlowableListener> taskListeners = new ArrayList<>();
protected String skipExpression;
protected String validateFormFields;
protected String taskIdVariableName;
protected Map<String, Set<String>> customUserIdentityLinks = new HashMap<>();
protected Map<String, Set<String>> customGroupIdentityLinks = new HashMap<>();
protected List<CustomProperty> customProperties = new ArrayList<>();
}

View File

@@ -0,0 +1,10 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.impl.task;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
/*
* @author ZZQ
* @Date 2024/3/18 11:28
*/
public class ExecuteTask extends FlowNode {
}

View File

@@ -0,0 +1,37 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.impl.task.impl;
import lombok.Data;
import org.apache.poi.hpsf.CustomProperty;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.task.ExecuteTask;
import java.util.*;
/*
* @author ZZQ
* @Date 2024/3/18 11:30
* 源UserTask
*/
@Data
public class FormTask extends ExecuteTask {
private String assignee;
private String owner;
private String priority;
private String formKey;
private boolean sameDeployment = true;
private String dueDate;
private String businessCalendarName;
private String category;
private String extensionId;
private List<String> candidateUsers = new ArrayList<>();
private List<String> candidateGroups = new ArrayList<>();
// private List<FormProperty> formProperties = new ArrayList<>();
// private List<FlowableListener> taskListeners = new ArrayList<>();
private String skipExpression;
private String validateFormFields;
private String taskIdVariableName;
private Map<String, Set<String>> customUserIdentityLinks = new HashMap<>();
private Map<String, Set<String>> customGroupIdentityLinks = new HashMap<>();
private List<CustomProperty> customProperties = new ArrayList<>();
}

View File

@@ -0,0 +1,15 @@
package org.nl.wms.flow_manage.flow.framework.entity.node.impl.task.impl;
import org.nl.wms.flow_manage.flow.framework.entity.node.impl.task.ExecuteTask;
/*
* @author ZZQ
* @Date 2024/3/18 11:30
*/
public class ScriptExecuteTask extends ExecuteTask {
protected String scriptFormat;
protected String script;
protected String resultVariable;
protected String skipExpression;
protected boolean autoStoreVariables;
}

View File

@@ -0,0 +1,13 @@
package org.nl.wms.flow_manage.flow.framework.process.nodeType;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/21 15:19
*/
public abstract class TypeHandler {
public abstract void handler(String param, ExecutionEntity entity);
}

View File

@@ -0,0 +1,17 @@
package org.nl.wms.flow_manage.flow.framework.process.nodeType.impl;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.process.nodeType.TypeHandler;
/*
* @author ZZQ
* @Date 2024/3/21 15:17
*/
public class ClassHandler extends TypeHandler {
@Override
public void handler(String param, ExecutionEntity entity) {
}
}

View File

@@ -0,0 +1,15 @@
package org.nl.wms.flow_manage.flow.framework.process.nodeType.impl;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.process.nodeType.TypeHandler;
/*
* @author ZZQ
* @Date 2024/3/21 15:16
*/
public class ExpressionHandler extends TypeHandler {
@Override
public void handler(String param, ExecutionEntity entity) {
}
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.framework.process.nodeType.impl;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.process.nodeType.TypeHandler;
/*
* @author ZZQ
* @Date 2024/3/21 15:16
*/
public class ScriptHandler extends TypeHandler {
@Override
public void handler(String param, ExecutionEntity entity) {
}
}

View File

@@ -0,0 +1,17 @@
package org.nl.wms.flow_manage.flow.service.deployment;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
/**
* <p>
* 流程部署信息 服务类
* </p>
*
* @author generator
* @since 2024-03-19
*/
public interface IActReProcdefService extends IService<ActReProcdef> {
}

View File

@@ -0,0 +1,75 @@
package org.nl.wms.flow_manage.flow.service.deployment.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import java.sql.Blob;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 流程版本号
* </p>
*
* @author generator
* @since 2024-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("act_re_procdef")
public class ActReProcdef implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private String deployment_id;
/**
* 模型key
*/
private String model_key;
/**
* 名称
*/
private String name;
/**
* 部署描述
*/
private String description;
/**
* 部署时间
*/
private String depl_time;
/**
* 版本号
*/
private String version;
/**
* 乐观锁
*/
private String category;
/**
* 模型JSON
*/
private String model_editor_json;
/**
* xml文件
*/
private Blob bytes;
/**
* 流程部署状态
*/
private String status;
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.service.deployment.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
/**
* <p>
* 流程版本号 Mapper 接口
* </p>
*
* @author generator
* @since 2024-03-19
*/
public interface ActReProcdefMapper extends BaseMapper<ActReProcdef> {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.nl.wms.flow_manage.flow.service.deployment.dao.mapper.ActReProcdefMapper">
</mapper>

View File

@@ -0,0 +1,21 @@
package org.nl.wms.flow_manage.flow.service.deployment.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.wms.flow_manage.flow.service.deployment.dao.mapper.ActReProcdefMapper;
import org.nl.wms.flow_manage.flow.service.deployment.IActReProcdefService;
import org.springframework.stereotype.Service;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
/**
* <p>
* 流程版本号 服务实现类
* </p>
*
* @author generator
* @since 2024-03-19
*/
@Service
public class ActReProcdefServiceImpl extends ServiceImpl<ActReProcdefMapper, ActReProcdef> implements IActReProcdefService {
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.service.execution;
import org.nl.wms.flow_manage.flow.service.execution.dao.ActRuExecution;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 流程实例表 服务类
* </p>
*
* @author generator
* @since 2024-03-21
*/
public interface IActRuExecutionService extends IService<ActRuExecution> {
}

View File

@@ -0,0 +1,15 @@
package org.nl.wms.flow_manage.flow.service.execution;
import org.nl.wms.flow_manage.flow.service.execution.dto.StartProcessInstanceVo;
/**
* @program: flow
* @description: 表单流程操作类
* @author: Bruce.Liu
* @create: 2023-02-19 14:20
**/
public interface IFlowOperationService {
Boolean startFormFlow(StartProcessInstanceVo params) ;
}

View File

@@ -0,0 +1,84 @@
package org.nl.wms.flow_manage.flow.service.execution.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 流程实例表
* </p>
*
* @author generator
* @since 2024-03-21
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("act_ru_execution")
public class ActRuExecution implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 流程实例id
*/
private String proc_inst_id;
/**
* 父流程id
*/
private String parent_id;
/**
* 当前实例对应版本的部署id
*/
private String deployment_id;
/**
* 当前实例执行节点id
*/
private String activity_id;
/**
* 当前实例是否启用
*/
private Boolean is_active;
/**
* 实例状态
*/
private String status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private String create_time;
/**
* 创建人
*/
private String create_id;
/**
* 修改时间
*/
private String update_time;
/**
* 业务主键
*/
private Integer buss_key;
/**
* 业务类型
*/
private Integer buss_type;
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.service.execution.dao.mapper;
import org.nl.wms.flow_manage.flow.service.execution.dao.ActRuExecution;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 流程实例表 Mapper 接口
* </p>
*
* @author generator
* @since 2024-03-21
*/
public interface ActRuExecutionMapper extends BaseMapper<ActRuExecution> {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.nl.wms.flow_manage.flow.service.execution.dao.mapper.ActRuExecutionMapper">
</mapper>

View File

@@ -0,0 +1,64 @@
package org.nl.wms.flow_manage.flow.service.execution.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* @Description: 启动流程参数Vo
* @Author: Bruce.liu
* @Since:18:12 2021/04/20
*/
@Data
public class StartProcessInstanceVo implements Serializable {
/**
* 流程定义key 必填
*/
private String processDefinitionKey;
/**
* 流程表单类型
*/
private String form_type;
/**
* 业务系统id 必填
*/
private String businessKey;
/**
* 启动流程变量 选填
*/
private Map<String, Object> variables;
/**
* 申请人工号 必填
*/
private String currentUserCode;
/**
* 系统标识 必填
*/
private String appSn;
/**
* 表单显示名称 必填
*/
private String formName;
/**
* 流程提交人工号 必填
*/
private String creator;
/**
* 老的流程实例id
*/
private String oldProcessInstanceId;
/**
*
* 是否走底表数据
*/
private boolean flowLevelFlag = true;
/**
* 要走流程部门ID
*/
private String deptId;
private JSONObject formData;
}

View File

@@ -0,0 +1,20 @@
package org.nl.wms.flow_manage.flow.service.execution.impl;
import org.nl.wms.flow_manage.flow.service.execution.dao.ActRuExecution;
import org.nl.wms.flow_manage.flow.service.execution.dao.mapper.ActRuExecutionMapper;
import org.nl.wms.flow_manage.flow.service.execution.IActRuExecutionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 流程实例表 服务实现类
* </p>
*
* @author generator
* @since 2024-03-21
*/
@Service
public class ActRuExecutionServiceImpl extends ServiceImpl<ActRuExecutionMapper, ActRuExecution> implements IActRuExecutionService {
}

View File

@@ -0,0 +1,38 @@
package org.nl.wms.flow_manage.flow.service.execution.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.wms.flow_manage.flow.service.deployment.IActReProcdefService;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
import org.nl.wms.flow_manage.flow.service.execution.IFlowOperationService;
import org.nl.wms.flow_manage.flow.service.execution.dto.StartProcessInstanceVo;
import org.nl.wms.flow_manage.flow.service.model.IActDeModelService;
import org.nl.wms.flow_manage.flow.service.model.dao.ActDeModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/*
* @author ZZQ
* @Date 2024/3/19 16:48
*/
@Service
public class FlowOperationServiceImpl implements IFlowOperationService {
@Autowired
IActDeModelService actDeModelService;
@Autowired
IActReProcdefService actReProcdefService;
@Override
public Boolean startFormFlow(StartProcessInstanceVo params) {
JSONObject formData = params.getFormData();
//查询当前部署的流程ACT_RE_PROCDEF
ActReProcdef deployment = actReProcdefService.getOne(new LambdaUpdateWrapper<ActReProcdef>().eq(ActReProcdef::getModel_key, params.getForm_type()));
if (deployment==null){
throw new BadRequestException("当前单据类型未配置业务流程");
}
return null;
}
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.service.model;
import org.nl.wms.flow_manage.flow.service.model.dao.ActDeModel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 模型表 服务类
* </p>
*
* @author generator
* @since 2024-03-18
*/
public interface IActDeModelService extends IService<ActDeModel> {
}

View File

@@ -0,0 +1,99 @@
package org.nl.wms.flow_manage.flow.service.model.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import java.sql.Blob;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 模型表
* </p>
*
* @author generator
* @since 2024-03-18
*/
@Data
@TableName("act_de_model")
public class ActDeModel implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private String id;
/**
* 模型名称
*/
private String name;
/**
* key
*/
private String model_key;
/**
* 模型描述
*/
private String description;
/**
* 模型注释
*/
private String model_comment;
/**
* 创建时间
*/
private String create_time;
/**
* 创建人
*/
private String create_id;
/**
* 修改时间
*/
private String update_time;
/**
* 修改人
*/
private String updated_id;
/**
* 版本号
*/
private Integer version;
/**
* 模型json数据
*/
private String model_editor_json;
/**
* 模型封面
*/
private Blob thumbnail;
/**
* 模型类型
*/
private Integer model_type;
/**
* 单据类型
*/
private String form_type;
/**
* 归属租户
*/
private String tenant_id;
}

View File

@@ -0,0 +1,16 @@
package org.nl.wms.flow_manage.flow.service.model.dao.mapper;
import org.nl.wms.flow_manage.flow.service.model.dao.ActDeModel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 模型表 Mapper 接口
* </p>
*
* @author generator
* @since 2024-03-18
*/
public interface ActDeModelMapper extends BaseMapper<ActDeModel> {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.nl.wms.flow_manage.flow.service.model.dao.mapper.ActDeModelMapper">
</mapper>

View File

@@ -0,0 +1,41 @@
package org.nl.wms.flow_manage.flow.service.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @program: flow
* @description: 高亮信息
* @author: Bruce.Liu
* @create: 2021-05-11 20:06
**/
@Data
public class HighLightedNodeVo implements Serializable {
public HighLightedNodeVo(List<String> highLightedFlows, List<String> activeActivityIds, String modelXml, String modelName) {
this.highLightedFlows = highLightedFlows;
this.activeActivityIds = activeActivityIds;
this.modelXml = modelXml;
this.modelName = modelName;
}
//高亮线id集合
private List<String> highLightedFlows;
//当前节点高亮节点id集合
private List<String> activeActivityIds;
/**
* 已经完成的历史节点集合
*/
private List<String> hisActiveActivityIds;
/**
* 未执行的节点id列表
*/
private List<String> nullActiveActivityIds;
//model的xml文件
private String modelXml;
//model的名称
private String modelName;
}

View File

@@ -0,0 +1,24 @@
package org.nl.wms.flow_manage.flow.service.model.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @program: flow
* @description: 模型的VO
* @author: Bruce.Liu
* @create: 2021-04-20 21:25
**/
@Data
public class ModelInfoVo implements Serializable {
private static final long serialVersionUID = -2434943659168309903L;
private String id;
private String modelId;
private String modelKey;
private String modelName;
private String fileName;
private String modelXml;
private String appSn;
private String categoryCode;
}

View File

@@ -0,0 +1,20 @@
package org.nl.wms.flow_manage.flow.service.model.impl;
import org.nl.wms.flow_manage.flow.service.model.dao.ActDeModel;
import org.nl.wms.flow_manage.flow.service.model.dao.mapper.ActDeModelMapper;
import org.nl.wms.flow_manage.flow.service.model.IActDeModelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 模型表 服务实现类
* </p>
*
* @author generator
* @since 2024-03-18
*/
@Service
public class ActDeModelServiceImpl extends ServiceImpl<ActDeModelMapper, ActDeModel> implements IActDeModelService {
}