diff --git a/pom.xml b/pom.xml index f7a7e08e..2565f144 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,6 @@ 1.2.13 5.7.12 5.3.39 - 6.8.0 @@ -219,17 +218,13 @@ ${ruoyi.version} + com.ruoyi - ruoyi-flowable + ruoyi-mill ${ruoyi.version} - - org.flowable - flowable-spring-boot-starter - ${flowable.version} - io.swagger swagger-annotations @@ -252,7 +247,7 @@ ruoyi-quartz ruoyi-generator ruoyi-common - ruoyi-flowable + ruoyi-mill pom diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 77dc6720..e4515457 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -61,9 +61,10 @@ ruoyi-generator + com.ruoyi - ruoyi-flowable + ruoyi-mill diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 5cd90580..5a9f095b 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -1,7 +1,7 @@ # 项目相关配置 ruoyi: # 名称 - name: RuoYi + name: 冷轧双机架二级控制系统 # 版本 version: 3.8.9 # 版权年份 @@ -128,9 +128,14 @@ xss: # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* -# flowable相关表 -flowable: - # true 会对数据库中所有表进行更新操作。如果表不存在,则自动创建(建议开发时使用) - database-schema-update: true - # 关闭定时任务JOB - async-executor-activate: false +# 冷轧二级控制系统 UDP 通信配置 +mill: + udp: + # 本地监听端口(接收 L3 下行电文) + local-port: 9001 + # L3 系统 IP 地址 + remote-host: 127.0.0.1 + # L3 系统 UDP 端口 + remote-port: 9000 + # 接收缓冲区大小(字节) + buffer-size: 4096 diff --git a/ruoyi-flowable/pom.xml b/ruoyi-flowable/pom.xml deleted file mode 100644 index e34be60d..00000000 --- a/ruoyi-flowable/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - ruoyi - com.ruoyi - 3.8.9 - - 4.0.0 - - ruoyi-flowable - - - - - com.ruoyi - ruoyi-framework - - - com.ruoyi - ruoyi-system - - - com.ruoyi - ruoyi-common - - - - - org.apache.commons - commons-lang3 - - - - - com.fasterxml.jackson.core - jackson-databind - - - - - com.alibaba.fastjson2 - fastjson2 - - - - org.projectlombok - lombok - true - - - io.swagger - swagger-annotations - compile - - - org.flowable - flowable-spring-boot-starter - - - - org.flowable - flowable-spring-security - - - - - com.baomidou - mybatis-plus-boot-starter - - - - - org.springframework.boot - spring-boot-starter-websocket - - - - - com.googlecode.aviator - aviator - 5.3.3 - - - - - - - - - - - - - - diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/constant/ProcessConstants.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/constant/ProcessConstants.java deleted file mode 100644 index 9967434e..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/constant/ProcessConstants.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.ruoyi.flowable.common.constant; - -/** - * 流程常量信息 - * - * @author Tony - * @date 2021/4/17 22:46 - */ -public class ProcessConstants { - - /** - * 动态数据 - */ - public static final String DYNAMIC = "dynamic"; - - /** - * 固定任务接收 - */ - public static final String FIXED = "fixed"; - - /** - * 单个审批人 - */ - public static final String ASSIGNEE = "assignee"; - - - /** - * 候选人 - */ - public static final String CANDIDATE_USERS = "candidateUsers"; - - - /** - * 审批组 - */ - public static final String CANDIDATE_GROUPS = "candidateGroups"; - - /** - * 单个审批人 - */ - public static final String PROCESS_APPROVAL = "approval"; - - /** - * 会签人员 - */ - public static final String PROCESS_MULTI_INSTANCE_USER = "userList"; - - /** - * nameapace - */ - public static final String NAMASPASE = "http://flowable.org/bpmn"; - - /** - * 会签节点 - */ - public static final String PROCESS_MULTI_INSTANCE = "multiInstance"; - - /** - * 自定义属性 dataType - */ - public static final String PROCESS_CUSTOM_DATA_TYPE = "dataType"; - - /** - * 自定义属性 userType - */ - public static final String PROCESS_CUSTOM_USER_TYPE = "userType"; - - /** - * 初始化人员 - */ - public static final String PROCESS_INITIATOR = "INITIATOR"; - - - /** - * 流程跳过 - */ - public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED"; - - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/enums/FlowComment.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/enums/FlowComment.java deleted file mode 100644 index d677170a..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/enums/FlowComment.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ruoyi.flowable.common.enums; - -/** - * 流程意见类型 - * - * @author Tony - * @date 2021/4/19 - */ -public enum FlowComment { - - /** - * 说明 - */ - NORMAL("1", "正常意见"), - REBACK("2", "退回意见"), - REJECT("3", "驳回意见"), - DELEGATE("4", "委派意见"), - ASSIGN("5", "转办意见"), - STOP("6", "终止流程"); - - /** - * 类型 - */ - private final String type; - - /** - * 说明 - */ - private final String remark; - - FlowComment(String type, String remark) { - this.type = type; - this.remark = remark; - } - - public String getType() { - return type; - } - - public String getRemark() { - return remark; - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/BaseEl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/BaseEl.java deleted file mode 100755 index 557429b7..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/BaseEl.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.ruoyi.flowable.common.expand.el; - -/** - * 扩展表达式 - * - * @author Tony - * @date 2023-03-04 09:10 - */ -public interface BaseEl { - -} - diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/FlowEl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/FlowEl.java deleted file mode 100755 index a6870ffb..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/common/expand/el/FlowEl.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ruoyi.flowable.common.expand.el; - -import com.ruoyi.system.service.ISysDeptService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -/** - * 扩展表达式 - * - * @author Tony - * @date 2023-03-04 12:10 - */ -@Component -@Slf4j -public class FlowEl implements BaseEl { - - @Resource - private ISysDeptService sysDeptService; - - public String findDeptLeader(String name){ - log.info("开始查询表达式变量值,getName"); - return name; - } - - public String getName(String name){ - log.info("开始查询表达式变量值,getName"); - return name; - } -} - diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/FlowableConfig.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/FlowableConfig.java deleted file mode 100644 index 212b8a94..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/FlowableConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.flowable.config; - -import org.flowable.engine.impl.db.DbIdGenerator; -import org.flowable.spring.SpringProcessEngineConfiguration; -import org.flowable.spring.boot.EngineConfigurationConfigurer; -import org.springframework.context.annotation.Configuration; - -/** - * 扩展流程配置 - * @author Tony - * @date 2022-12-26 10:24 - */ -@Configuration -public class FlowableConfig implements EngineConfigurationConfigurer { - @Override - public void configure(SpringProcessEngineConfiguration engineConfiguration) { - engineConfiguration.setActivityFontName("宋体"); - engineConfiguration.setLabelFontName("宋体"); - engineConfiguration.setAnnotationFontName("宋体"); - engineConfiguration.setIdGenerator(new DbIdGenerator()); - } - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/MyDefaultProcessDiagramCanvas.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/MyDefaultProcessDiagramCanvas.java deleted file mode 100644 index 3233c6d4..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/config/MyDefaultProcessDiagramCanvas.java +++ /dev/null @@ -1,95 +0,0 @@ -//package com.ruoyi.flowable.config; -// -//import com.sun.prism.paint.Color; -//import org.flowable.bpmn.model.AssociationDirection; -//import org.flowable.image.impl.DefaultProcessDiagramCanvas; -// -//import java.awt.*; -//import java.awt.geom.Line2D; -//import java.awt.geom.RoundRectangle2D; -// -///** -// * @author Tony -// * @date 2021-04-03 -// */ -//public class MyDefaultProcessDiagramCanvas extends DefaultProcessDiagramCanvas { -// //设置高亮线的颜色 这里我设置成绿色 -// protected static Color HIGHLIGHT_SEQUENCEFLOW_COLOR = Color.GREEN; -// -// public MyDefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) { -// super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); -// } -// -// public MyDefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType) { -// super(width, height, minX, minY, imageType); -// } -// -// -// /** -// * 画线颜色设置 -// */ -// @Override -// public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, -// AssociationDirection associationDirection, boolean highLighted, double scaleFactor) { -// -// Paint originalPaint = g.getPaint(); -// Stroke originalStroke = g.getStroke(); -// -// g.setPaint(CONNECTION_COLOR); -// if (connectionType.equals("association")) { -// g.setStroke(ASSOCIATION_STROKE); -// } else if (highLighted) { -// //设置线的颜色 -// g.setPaint(originalPaint); -// g.setStroke(HIGHLIGHT_FLOW_STROKE); -// } -// -// for (int i = 1; i < xPoints.length; i++) { -// Integer sourceX = xPoints[i - 1]; -// Integer sourceY = yPoints[i - 1]; -// Integer targetX = xPoints[i]; -// Integer targetY = yPoints[i]; -// Line2D.Double line = new Line2D.Double(sourceX, sourceY, targetX, targetY); -// g.draw(line); -// } -// -// if (isDefault) { -// Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]); -// drawDefaultSequenceFlowIndicator(line, scaleFactor); -// } -// -// if (conditional) { -// Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]); -// drawConditionalSequenceFlowIndicator(line, scaleFactor); -// } -// -// if (associationDirection == AssociationDirection.ONE || associationDirection == AssociationDirection.BOTH) { -// Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2], yPoints[xPoints.length - 2], xPoints[xPoints.length - 1], yPoints[xPoints.length - 1]); -// drawArrowHead(line, scaleFactor); -// } -// if (associationDirection == AssociationDirection.BOTH) { -// Line2D.Double line = new Line2D.Double(xPoints[1], yPoints[1], xPoints[0], yPoints[0]); -// drawArrowHead(line, scaleFactor); -// } -// g.setPaint(originalPaint); -// g.setStroke(originalStroke); -// } -// -// /** -// * 高亮节点设置 -// */ -// @Override -// public void drawHighLight(int x, int y, int width, int height) { -// Paint originalPaint = g.getPaint(); -// Stroke originalStroke = g.getStroke(); -// //设置高亮节点的颜色 -// g.setPaint(HIGHLIGHT_COLOR); -// g.setStroke(THICK_TASK_BORDER_STROKE); -// -// RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); -// g.draw(rect); -// -// g.setPaint(originalPaint); -// g.setStroke(originalStroke); -// } -//} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java deleted file mode 100644 index 5b2f6096..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.ruoyi.flowable.controller; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.system.domain.FlowProcDefDto; -import com.ruoyi.flowable.domain.dto.FlowSaveXmlVo; -import com.ruoyi.flowable.service.IFlowDefinitionService; -import com.ruoyi.system.domain.SysExpression; -import com.ruoyi.system.service.ISysExpressionService; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.annotation.Resource; -import javax.imageio.ImageIO; -import javax.servlet.http.HttpServletResponse; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; - -/** - *

- * 工作流程定义 - *

- * - * @author Tony - * @date 2021-04-03 - */ -@Slf4j -@Api(tags = "流程定义") -@RestController -@RequestMapping("/flowable/definition") -public class FlowDefinitionController extends BaseController { - - @Autowired - private IFlowDefinitionService flowDefinitionService; - - @Autowired - private ISysUserService userService; - - @Resource - private ISysRoleService sysRoleService; - @Resource - private ISysExpressionService sysExpressionService; - - @GetMapping(value = "/list") - @ApiOperation(value = "流程定义列表", response = FlowProcDefDto.class) - public AjaxResult list(@ApiParam(value = "当前页码", required = true) @RequestParam Integer pageNum, - @ApiParam(value = "每页条数", required = true) @RequestParam Integer pageSize, - @ApiParam(value = "流程名称", required = false) @RequestParam(required = false) String name) { - return AjaxResult.success(flowDefinitionService.list(name, pageNum, pageSize)); - } - - - @ApiOperation(value = "导入流程文件", notes = "上传bpmn20的xml文件") - @PostMapping("/import") - public AjaxResult importFile(@RequestParam(required = false) String name, - @RequestParam(required = false) String category, - MultipartFile file) { - InputStream in = null; - try { - in = file.getInputStream(); - flowDefinitionService.importFile(name, category, in); - } catch (Exception e) { - log.error("导入失败:", e); - return AjaxResult.success(e.getMessage()); - } finally { - try { - if (in != null) { - in.close(); - } - } catch (IOException e) { - log.error("关闭输入流出错", e); - } - } - - return AjaxResult.success("导入成功"); - } - - - @ApiOperation(value = "读取xml文件") - @GetMapping("/readXml/{deployId}") - public AjaxResult readXml(@ApiParam(value = "流程定义id") @PathVariable(value = "deployId") String deployId) { - try { - return flowDefinitionService.readXml(deployId); - } catch (Exception e) { - return AjaxResult.error("加载xml文件异常"); - } - - } - - @ApiOperation(value = "读取图片文件") - @GetMapping("/readImage/{deployId}") - public void readImage(@ApiParam(value = "流程定义id") @PathVariable(value = "deployId") String deployId, HttpServletResponse response) { - OutputStream os = null; - BufferedImage image = null; - try { - image = ImageIO.read(flowDefinitionService.readImage(deployId)); - response.setContentType("image/png"); - os = response.getOutputStream(); - if (image != null) { - ImageIO.write(image, "png", os); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (os != null) { - os.flush(); - os.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - - @ApiOperation(value = "保存流程设计器内的xml文件") - @Log(title = "流程定义", businessType = BusinessType.INSERT) - @PostMapping("/save") - public AjaxResult save(@RequestBody FlowSaveXmlVo vo) { - InputStream in = null; - try { - in = new ByteArrayInputStream(vo.getXml().getBytes(StandardCharsets.UTF_8)); - flowDefinitionService.importFile(vo.getName(), vo.getCategory(), in); - } catch (Exception e) { - log.error("导入失败:", e); - return AjaxResult.error(e.getMessage()); - } finally { - try { - if (in != null) { - in.close(); - } - } catch (IOException e) { - log.error("关闭输入流出错", e); - } - } - - return AjaxResult.success("导入成功"); - } - - @ApiOperation(value = "发起流程") - @Log(title = "发起流程", businessType = BusinessType.INSERT) - @PostMapping("/start/{procDefId}") - public AjaxResult start(@ApiParam(value = "流程定义id") @PathVariable(value = "procDefId") String procDefId, - @ApiParam(value = "变量集合,json对象") @RequestBody Map variables) { - return flowDefinitionService.startProcessInstanceById(procDefId, variables); - } - - @ApiOperation(value = "激活或挂起流程定义") - @Log(title = "激活/挂起流程", businessType = BusinessType.UPDATE) - @PutMapping(value = "/updateState") - public AjaxResult updateState(@ApiParam(value = "1:激活,2:挂起", required = true) @RequestParam Integer state, - @ApiParam(value = "流程部署ID", required = true) @RequestParam String deployId) { - flowDefinitionService.updateState(state, deployId); - return AjaxResult.success(); - } - - @ApiOperation(value = "删除流程") - @Log(title = "删除流程", businessType = BusinessType.DELETE) - @DeleteMapping(value = "/{deployIds}") - public AjaxResult delete(@PathVariable String[] deployIds) { - for (String deployId : deployIds) { - flowDefinitionService.delete(deployId); - } - return AjaxResult.success(); - } - - @ApiOperation(value = "指定流程办理人员列表") - @GetMapping("/userList") - public AjaxResult userList(SysUser user) { - List list = userService.selectUserList(user); - return AjaxResult.success(list); - } - - @ApiOperation(value = "指定流程办理组列表") - @GetMapping("/roleList") - public AjaxResult roleList(SysRole role) { - List list = sysRoleService.selectRoleList(role); - return AjaxResult.success(list); - } - - @ApiOperation(value = "指定流程达式列表") - @GetMapping("/expList") - public AjaxResult expList(SysExpression sysExpression) { - List list = sysExpressionService.selectSysExpressionList(sysExpression); - return AjaxResult.success(list); - } - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowInstanceController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowInstanceController.java deleted file mode 100644 index 427915ae..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowInstanceController.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ruoyi.flowable.controller; - - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import com.ruoyi.flowable.service.IFlowInstanceService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -/** - *

工作流流程实例管理

- * - * @author Tony - * @date 2021-04-03 - */ -@Slf4j -@Api(tags = "工作流流程实例管理") -@RestController -@RequestMapping("/flowable/instance") -public class FlowInstanceController extends BaseController { - - @Autowired - private IFlowInstanceService flowInstanceService; - - @ApiOperation(value = "根据流程定义id启动流程实例") - @PostMapping("/startBy/{procDefId}") - public AjaxResult startById(@ApiParam(value = "流程定义id") @PathVariable(value = "procDefId") String procDefId, - @ApiParam(value = "变量集合,json对象") @RequestBody Map variables) { - return flowInstanceService.startProcessInstanceById(procDefId, variables); - - } - - @ApiOperation(value = "激活或挂起流程实例") - @PostMapping(value = "/updateState") - public AjaxResult updateState(@ApiParam(value = "1:激活,2:挂起", required = true) @RequestParam Integer state, - @ApiParam(value = "流程实例ID", required = true) @RequestParam String instanceId) { - flowInstanceService.updateState(state,instanceId); - return AjaxResult.success(); - } - - @ApiOperation("结束流程实例") - @PostMapping(value = "/stopProcessInstance") - public AjaxResult stopProcessInstance(@RequestBody FlowTaskVo flowTaskVo) { - flowInstanceService.stopProcessInstance(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "删除流程实例") - @Log(title = "删除任务", businessType = BusinessType.DELETE) - @DeleteMapping(value = "/delete/{instanceIds}") - public AjaxResult delete(@ApiParam(value = "流程实例ID", required = true) @PathVariable String[] instanceIds, - @ApiParam(value = "删除原因") @RequestParam(required = false) String deleteReason) { - for (String instanceId : instanceIds) { - flowInstanceService.delete(instanceId,deleteReason); - } - return AjaxResult.success(); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowTaskController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowTaskController.java deleted file mode 100644 index 7d6abcf2..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowTaskController.java +++ /dev/null @@ -1,277 +0,0 @@ -package com.ruoyi.flowable.controller; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.flowable.domain.dto.FlowTaskDto; -import com.ruoyi.flowable.domain.vo.FlowQueryVo; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import com.ruoyi.flowable.service.IFlowTaskService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.imageio.ImageIO; -import javax.servlet.http.HttpServletResponse; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - *

工作流任务管理

- * - * @author Tony - * @date 2021-04-03 - */ -@Slf4j -@Api(tags = "工作流流程任务管理") -@RestController -@RequestMapping("/flowable/task") -public class FlowTaskController extends BaseController { - - @Autowired - private IFlowTaskService flowTaskService; - - @ApiOperation(value = "我发起的流程", response = FlowTaskDto.class) - @GetMapping(value = "/myProcess") - public AjaxResult myProcess(FlowQueryVo queryVo) { - return flowTaskService.myProcess(queryVo); - } - - @ApiOperation(value = "取消申请", response = FlowTaskDto.class) - @Log(title = "取消申请", businessType = BusinessType.UPDATE) - @PostMapping(value = "/stopProcess") - public AjaxResult stopProcess(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.stopProcess(flowTaskVo); - } - - @ApiOperation(value = "撤回流程", response = FlowTaskDto.class) - @Log(title = "撤回流程", businessType = BusinessType.UPDATE) - @PostMapping(value = "/revokeProcess") - public AjaxResult revokeProcess(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.revokeProcess(flowTaskVo); - } - - @ApiOperation(value = "获取待办列表", response = FlowTaskDto.class) - @GetMapping(value = "/todoList") - public AjaxResult todoList(FlowQueryVo queryVo) { - return flowTaskService.todoList(queryVo); - } - - @ApiOperation(value = "获取已办任务", response = FlowTaskDto.class) - @GetMapping(value = "/finishedList") - public AjaxResult finishedList(FlowQueryVo queryVo) { - return flowTaskService.finishedList(queryVo); - } - - - @ApiOperation(value = "流程历史流转记录", response = FlowTaskDto.class) - @GetMapping(value = "/flowRecord") - public AjaxResult flowRecord(String procInsId, String deployId) { - return flowTaskService.flowRecord(procInsId, deployId); - } - - @ApiOperation(value = "根据任务ID查询挂载的表单信息") - @GetMapping(value = "/getTaskForm") - public AjaxResult getTaskForm(String taskId) { - return flowTaskService.getTaskForm(taskId); - } - - - @ApiOperation(value = "流程初始化表单", response = FlowTaskDto.class) - @GetMapping(value = "/flowFormData") - public AjaxResult flowFormData(String deployId) { - return flowTaskService.flowFormData(deployId); - } - - @ApiOperation(value = "获取流程变量", response = FlowTaskDto.class) - @GetMapping(value = "/processVariables/{taskId}") - public AjaxResult processVariables(@ApiParam(value = "流程任务Id") @PathVariable(value = "taskId") String taskId) { - return flowTaskService.processVariables(taskId); - } - - @ApiOperation(value = "审批任务") - @Log(title = "审批任务", businessType = BusinessType.UPDATE) - @PostMapping(value = "/complete") - public AjaxResult complete(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.complete(flowTaskVo); - } - - @ApiOperation(value = "驳回任务") - @Log(title = "驳回任务", businessType = BusinessType.UPDATE) - @PostMapping(value = "/reject") - public AjaxResult taskReject(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.taskReject(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "退回任务") - @Log(title = "退回任务", businessType = BusinessType.UPDATE) - @PostMapping(value = "/return") - public AjaxResult taskReturn(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.taskReturn(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "获取所有可回退的节点") - @PostMapping(value = "/returnList") - public AjaxResult findReturnTaskList(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.findReturnTaskList(flowTaskVo); - } - - @ApiOperation(value = "删除任务") - @Log(title = "删除任务", businessType = BusinessType.DELETE) - @DeleteMapping(value = "/delete") - public AjaxResult delete(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.deleteTask(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "认领/签收任务") - @PostMapping(value = "/claim") - public AjaxResult claim(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.claim(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "取消认领/签收任务") - @PostMapping(value = "/unClaim") - public AjaxResult unClaim(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.unClaim(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "委派任务") - @PostMapping(value = "/delegateTask") - public AjaxResult delegate(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.delegateTask(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "任务归还") - @PostMapping(value = "/resolveTask") - public AjaxResult resolveTask(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.resolveTask(flowTaskVo); - return AjaxResult.success(); - } - - @ApiOperation(value = "转办任务") - @PostMapping(value = "/assignTask") - public AjaxResult assign(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.assignTask(flowTaskVo); - return AjaxResult.success(); - } - - @PostMapping(value = "/addMultiInstanceExecution") - @ApiOperation(value = "多实例加签") - public AjaxResult addMultiInstanceExecution(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.addMultiInstanceExecution(flowTaskVo); - return AjaxResult.success("加签成功"); - } - - @PostMapping(value = "/deleteMultiInstanceExecution") - @ApiOperation(value = "多实例减签") - public AjaxResult deleteMultiInstanceExecution(@RequestBody FlowTaskVo flowTaskVo) { - flowTaskService.deleteMultiInstanceExecution(flowTaskVo); - return AjaxResult.success("减签成功"); - } - - @ApiOperation(value = "获取下一节点") - @PostMapping(value = "/nextFlowNode") - public AjaxResult getNextFlowNode(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.getNextFlowNode(flowTaskVo); - } - - @ApiOperation(value = "流程发起时获取下一节点") - @PostMapping(value = "/nextFlowNodeByStart") - public AjaxResult getNextFlowNodeByStart(@RequestBody FlowTaskVo flowTaskVo) { - return flowTaskService.getNextFlowNodeByStart(flowTaskVo); - } - - /** - * 生成流程图 - * - * @param processId 任务ID - */ - @GetMapping("/diagram/{processId}") - public void genProcessDiagram(HttpServletResponse response, - @PathVariable("processId") String processId) { - InputStream inputStream = flowTaskService.diagram(processId); - OutputStream os = null; - BufferedImage image = null; - try { - image = ImageIO.read(inputStream); - response.setContentType("image/png"); - os = response.getOutputStream(); - if (image != null) { - ImageIO.write(image, "png", os); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (os != null) { - os.flush(); - os.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - /** - * 获取流程执行节点 - * - * @param procInsId 流程实例编号 - * @param procInsId 任务执行编号 - */ - @GetMapping("/flowViewer/{procInsId}/{executionId}") - public AjaxResult getFlowViewer(@PathVariable("procInsId") String procInsId, - @PathVariable("executionId") String executionId) { - return flowTaskService.getFlowViewer(procInsId, executionId); - } - - /** - * 流程节点信息 - * - * @param procInsId 流程实例id - * @return - */ - @GetMapping("/flowXmlAndNode") - public AjaxResult flowXmlAndNode(@RequestParam(value = "procInsId", required = false) String procInsId, - @RequestParam(value = "deployId", required = false) String deployId) { - return flowTaskService.flowXmlAndNode(procInsId, deployId); - } - - /** - * 流程节点表单 - * - * @param taskId 流程任务编号 - * @return - */ - @GetMapping("/flowTaskForm") - public AjaxResult flowTaskForm(@RequestParam(value = "taskId", required = false) String taskId) throws Exception { - return flowTaskService.flowTaskForm(taskId); - } - - - /** - * 流程节点信息 - * - * @param procInsId 流程实例编号 - * @param elementId 流程节点编号 - * @return - */ - @GetMapping("/flowTaskInfo") - public AjaxResult flowTaskInfo(@RequestParam(value = "procInsId") String procInsId, - @RequestParam(value = "elementId") String elementId){ - return flowTaskService.flowTaskInfo(procInsId,elementId); - } - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysExpressionController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysExpressionController.java deleted file mode 100755 index abc45252..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysExpressionController.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.ruoyi.flowable.controller; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.system.domain.SysExpression; -import com.ruoyi.system.service.ISysExpressionService; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.common.core.page.TableDataInfo; - -/** - * 流程达式Controller - * - * @author ruoyi - * @date 2022-12-12 - */ -@RestController -@RequestMapping("/system/expression") -public class SysExpressionController extends BaseController -{ - @Autowired - private ISysExpressionService sysExpressionService; - - /** - * 查询流程达式列表 - */ - @PreAuthorize("@ss.hasPermi('system:expression:list')") - @GetMapping("/list") - public TableDataInfo list(SysExpression sysExpression) - { - startPage(); - List list = sysExpressionService.selectSysExpressionList(sysExpression); - return getDataTable(list); - } - - /** - * 导出流程达式列表 - */ - @PreAuthorize("@ss.hasPermi('system:expression:export')") - @Log(title = "流程达式", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, SysExpression sysExpression) - { - List list = sysExpressionService.selectSysExpressionList(sysExpression); - ExcelUtil util = new ExcelUtil(SysExpression.class); - util.exportExcel(response, list, "流程达式数据"); - } - - /** - * 获取流程达式详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:expression:query')") - @GetMapping(value = "/{id}") - public AjaxResult getInfo(@PathVariable("id") Long id) - { - return success(sysExpressionService.selectSysExpressionById(id)); - } - - /** - * 新增流程达式 - */ - @PreAuthorize("@ss.hasPermi('system:expression:add')") - @Log(title = "流程达式", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysExpression sysExpression) - { - return toAjax(sysExpressionService.insertSysExpression(sysExpression)); - } - - /** - * 修改流程达式 - */ - @PreAuthorize("@ss.hasPermi('system:expression:edit')") - @Log(title = "流程达式", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysExpression sysExpression) - { - return toAjax(sysExpressionService.updateSysExpression(sysExpression)); - } - - /** - * 删除流程达式 - */ - @PreAuthorize("@ss.hasPermi('system:expression:remove')") - @Log(title = "流程达式", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public AjaxResult remove(@PathVariable Long[] ids) - { - return toAjax(sysExpressionService.deleteSysExpressionByIds(ids)); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysFormController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysFormController.java deleted file mode 100644 index 92ce54fb..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysFormController.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.ruoyi.flowable.controller; - -import java.util.List; - -import com.ruoyi.flowable.service.ISysDeployFormService; -import com.ruoyi.system.domain.SysDeployForm; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.system.domain.SysForm; -import com.ruoyi.flowable.service.ISysFormService; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.common.core.page.TableDataInfo; - -/** - * 流程表单Controller - * - * @author Tony - * @date 2021-04-03 - */ -@RestController -@RequestMapping("/flowable/form") -public class SysFormController extends BaseController { - @Autowired - private ISysFormService SysFormService; - - @Autowired - private ISysDeployFormService sysDeployFormService; - - /** - * 查询流程表单列表 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:list')") - @GetMapping("/list") - public TableDataInfo list(SysForm sysForm) { - startPage(); - List list = SysFormService.selectSysFormList(sysForm); - return getDataTable(list); - } - - @GetMapping("/formList") - public AjaxResult formList(SysForm sysForm) { - List list = SysFormService.selectSysFormList(sysForm); - return AjaxResult.success(list); - } - /** - * 导出流程表单列表 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:export')") - @Log(title = "流程表单", businessType = BusinessType.EXPORT) - @GetMapping("/export") - public AjaxResult export(SysForm sysForm) { - List list = SysFormService.selectSysFormList(sysForm); - ExcelUtil util = new ExcelUtil(SysForm.class); - return util.exportExcel(list, "form"); - } - - /** - * 获取流程表单详细信息 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:query')") - @GetMapping(value = "/{formId}") - public AjaxResult getInfo(@PathVariable("formId") Long formId) { - return AjaxResult.success(SysFormService.selectSysFormById(formId)); - } - - /** - * 新增流程表单 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:add')") - @Log(title = "流程表单", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysForm sysForm) { - return toAjax(SysFormService.insertSysForm(sysForm)); - } - - /** - * 修改流程表单 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:edit')") - @Log(title = "流程表单", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysForm sysForm) { - return toAjax(SysFormService.updateSysForm(sysForm)); - } - - /** - * 删除流程表单 - */ - @PreAuthorize("@ss.hasPermi('flowable:form:remove')") - @Log(title = "流程表单", businessType = BusinessType.DELETE) - @DeleteMapping("/{formIds}") - public AjaxResult remove(@PathVariable Long[] formIds) { - return toAjax(SysFormService.deleteSysFormByIds(formIds)); - } - - - /** - * 挂载流程表单 - */ - @Log(title = "流程表单", businessType = BusinessType.INSERT) - @PostMapping("/addDeployForm") - public AjaxResult addDeployForm(@RequestBody SysDeployForm sysDeployForm) { - return toAjax(sysDeployFormService.insertSysDeployForm(sysDeployForm)); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysListenerController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysListenerController.java deleted file mode 100755 index 500a9fbb..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/SysListenerController.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.ruoyi.flowable.controller; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.system.domain.SysListener; -import com.ruoyi.system.service.ISysListenerService; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.common.core.page.TableDataInfo; - -/** - * 流程监听Controller - * - * @author Tony - * @date 2022-12-25 - */ -@RestController -@RequestMapping("/system/listener") -public class SysListenerController extends BaseController -{ - @Autowired - private ISysListenerService sysListenerService; - - /** - * 查询流程监听列表 - */ - @PreAuthorize("@ss.hasPermi('system:listener:list')") - @GetMapping("/list") - public TableDataInfo list(SysListener sysListener) - { - startPage(); - List list = sysListenerService.selectSysListenerList(sysListener); - return getDataTable(list); - } - - /** - * 导出流程监听列表 - */ - @PreAuthorize("@ss.hasPermi('system:listener:export')") - @Log(title = "流程监听", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, SysListener sysListener) - { - List list = sysListenerService.selectSysListenerList(sysListener); - ExcelUtil util = new ExcelUtil(SysListener.class); - util.exportExcel(response, list, "流程监听数据"); - } - - /** - * 获取流程监听详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:listener:query')") - @GetMapping(value = "/{id}") - public AjaxResult getInfo(@PathVariable("id") Long id) - { - return success(sysListenerService.selectSysListenerById(id)); - } - - /** - * 新增流程监听 - */ - @PreAuthorize("@ss.hasPermi('system:listener:add')") - @Log(title = "流程监听", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysListener sysListener) - { - return toAjax(sysListenerService.insertSysListener(sysListener)); - } - - /** - * 修改流程监听 - */ - @PreAuthorize("@ss.hasPermi('system:listener:edit')") - @Log(title = "流程监听", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysListener sysListener) - { - return toAjax(sysListenerService.updateSysListener(sysListener)); - } - - /** - * 删除流程监听 - */ - @PreAuthorize("@ss.hasPermi('system:listener:remove')") - @Log(title = "流程监听", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public AjaxResult remove(@PathVariable Long[] ids) - { - return toAjax(sysListenerService.deleteSysListenerByIds(ids)); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowCommentDto.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowCommentDto.java deleted file mode 100644 index fdc4e068..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowCommentDto.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import lombok.Builder; -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Tony - * @date 2021/3/28 15:50 - */ -@Data -@Builder -public class FlowCommentDto implements Serializable { - - /** - * 意见类别 0 正常意见 1 退回意见 2 驳回意见 - */ - private String type; - - /** - * 意见内容 - */ - private String comment; -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowFromFieldDTO.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowFromFieldDTO.java deleted file mode 100644 index a74b83b2..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowFromFieldDTO.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Tony - * @date 2021/3/31 23:20 - */ -@Data -public class FlowFromFieldDTO implements Serializable { - - private Object fields; -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java deleted file mode 100644 index b7316882..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.entity.SysUser; -import lombok.Data; - -import java.io.Serializable; -import java.util.List; - -/** - * 动态人员、组 - * @author Tony - * @date 2021/4/17 22:59 - */ -@Data -public class FlowNextDto implements Serializable { - - /** - * 审批人类型 - */ - private String type; - - /** - * 是否需要动态指定任务审批人 - */ - private String dataType; - - /** - * 流程变量 - */ - private String vars; - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowSaveXmlVo.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowSaveXmlVo.java deleted file mode 100644 index 6c98e716..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowSaveXmlVo.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Tony - * @date 2021/3/28 19:48 - */ -@Data -public class FlowSaveXmlVo implements Serializable { - - /** - * 流程名称 - */ - private String name; - - /** - * 流程分类 - */ - private String category; - - /** - * xml 文件 - */ - private String xml; -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowTaskDto.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowTaskDto.java deleted file mode 100644 index 63345107..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowTaskDto.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.ruoyi.common.core.domain.entity.SysUser; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Getter; -import lombok.Setter; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - *

工作流任务

- * - * @author Tony - * @date 2021-04-03 - */ -@Getter -@Setter -@ApiModel("工作流任务相关-返回参数") -public class FlowTaskDto implements Serializable { - - @ApiModelProperty("任务编号") - private String taskId; - - @ApiModelProperty("任务执行编号") - private String executionId; - - @ApiModelProperty("任务名称") - private String taskName; - - @ApiModelProperty("任务Key") - private String taskDefKey; - - @ApiModelProperty("任务执行人Id") - private Long assigneeId; - - @ApiModelProperty("部门名称") - private String deptName; - - @ApiModelProperty("流程发起人部门名称") - private String startDeptName; - - @ApiModelProperty("任务执行人名称") - private String assigneeName; - @ApiModelProperty("任务执行人部门") - private String assigneeDeptName;; - - @ApiModelProperty("流程发起人Id") - private String startUserId; - - @ApiModelProperty("流程发起人名称") - private String startUserName; - - @ApiModelProperty("流程类型") - private String category; - - @ApiModelProperty("流程变量信息") - private Object variables; - - @ApiModelProperty("局部变量信息") - private Object taskLocalVars; - - @ApiModelProperty("流程部署编号") - private String deployId; - - @ApiModelProperty("流程ID") - private String procDefId; - - @ApiModelProperty("流程key") - private String procDefKey; - - @ApiModelProperty("流程定义名称") - private String procDefName; - - @ApiModelProperty("流程定义内置使用版本") - private int procDefVersion; - - @ApiModelProperty("流程实例ID") - private String procInsId; - - @ApiModelProperty("历史流程实例ID") - private String hisProcInsId; - - @ApiModelProperty("任务耗时") - private String duration; - - @ApiModelProperty("任务意见") - private FlowCommentDto comment; - - @ApiModelProperty("候选执行人") - private String candidate; - - @ApiModelProperty("任务创建时间") - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private Date createTime; - - @ApiModelProperty("任务完成时间") - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private Date finishTime; - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowViewerDto.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowViewerDto.java deleted file mode 100644 index 5914d7dd..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowViewerDto.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.flowable.domain.dto; - -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Tony - * @date 2021/4/21 20:55 - */ -@Data -public class FlowViewerDto implements Serializable { - - /** - * 流程key - */ - private String key; - - /** - * 是否完成(已经审批) - */ - private boolean completed; -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowQueryVo.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowQueryVo.java deleted file mode 100644 index c52957fb..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowQueryVo.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.ruoyi.flowable.domain.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; -import java.util.Map; - -/** - *

流程任务

- * - * @author Tony - * @date 2021-04-03 - */ -@Data -@ApiModel("工作流任务相关--请求参数") -public class FlowQueryVo { - - @ApiModelProperty("流程名称") - private String name; - - @ApiModelProperty("开始时间") - private String startTime; - - @ApiModelProperty("结束时间") - private String endTime; - - @ApiModelProperty("当前页码") - private Integer pageNum; - - @ApiModelProperty("每页条数") - private Integer pageSize; - - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowTaskVo.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowTaskVo.java deleted file mode 100644 index db8def9d..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowTaskVo.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.flowable.domain.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; -import java.util.Map; - -/** - *

流程任务

- * - * @author Tony - * @date 2021-04-03 - */ -@Data -@ApiModel("工作流任务相关--请求参数") -public class FlowTaskVo { - - @ApiModelProperty("任务Id") - private String taskId; - - @ApiModelProperty("用户Id") - private String userId; - - @ApiModelProperty("任务意见") - private String comment; - - @ApiModelProperty("流程实例Id") - private String instanceId; - - @ApiModelProperty("节点") - private String targetKey; - - private String deploymentId; - @ApiModelProperty("流程环节定义ID") - private String defId; - - @ApiModelProperty("子执行流ID") - private String currentChildExecutionId; - - @ApiModelProperty("子执行流是否已执行") - private Boolean flag; - - @ApiModelProperty("流程变量信息") - private Map variables; - - @ApiModelProperty("审批人") - private String assignee; - - @ApiModelProperty("候选人") - private List candidateUsers; - - @ApiModelProperty("审批组") - private List candidateGroups; -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/ReturnTaskNodeVo.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/ReturnTaskNodeVo.java deleted file mode 100644 index 0221bb9d..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/ReturnTaskNodeVo.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ruoyi.flowable.domain.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; -import java.util.Map; - -/** - *

可退回节点

- * - * @author tony - * @date 2022-04-23 11:01:52 - */ -@Data -@ApiModel("可退回节点") -public class ReturnTaskNodeVo { - - @ApiModelProperty("任务Id") - private String id; - - @ApiModelProperty("用户Id") - private String name; - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/factory/FlowServiceFactory.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/factory/FlowServiceFactory.java deleted file mode 100644 index 86fb71b0..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/factory/FlowServiceFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ruoyi.flowable.factory; - -import lombok.Getter; -import org.flowable.engine.*; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -/** - * flowable 引擎注入封装 - * @author Tony - * @date 2021-04-03 - */ -@Component -@Getter -public class FlowServiceFactory { - - @Resource - protected RepositoryService repositoryService; - - @Resource - protected RuntimeService runtimeService; - - @Resource - protected IdentityService identityService; - - @Resource - protected TaskService taskService; - - @Resource - protected HistoryService historyService; - - @Resource - protected ManagementService managementService; - - @Qualifier("processEngine") - @Resource - protected ProcessEngine processEngine; - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramCanvas.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramCanvas.java deleted file mode 100644 index d50017ea..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramCanvas.java +++ /dev/null @@ -1,370 +0,0 @@ -package com.ruoyi.flowable.flow; - -import org.flowable.bpmn.model.AssociationDirection; -import org.flowable.bpmn.model.GraphicInfo; -import org.flowable.image.impl.DefaultProcessDiagramCanvas; -import org.flowable.image.util.ReflectUtil; - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.font.FontRenderContext; -import java.awt.font.LineBreakMeasurer; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; - -/** - * @author Tony - * @date 2021/4/4 23:58 - */ -public class CustomProcessDiagramCanvas extends DefaultProcessDiagramCanvas { - //定义走过流程连线颜色为绿色 - protected static Color HIGHLIGHT_SequenceFlow_COLOR = Color.GREEN; - //设置未走过流程的连接线颜色 - protected static Color CONNECTION_COLOR = Color.BLACK; - //设置flows连接线字体颜色red - protected static Color LABEL_COLOR = new Color(0, 0, 0); - //高亮显示task框颜色 - protected static Color HIGHLIGHT_COLOR = Color.GREEN; - protected static Color HIGHLIGHT_COLOR1 = Color.RED; - - public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) { - super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); - this.initialize(imageType); - } - - /** - * 重写绘制连线的方式,设置绘制颜色 - * @param xPoints - * @param yPoints - * @param conditional - * @param isDefault - * @param connectionType - * @param associationDirection - * @param highLighted - * @param scaleFactor - */ - @Override - public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDirection, boolean highLighted, double scaleFactor) { - Paint originalPaint = this.g.getPaint(); - Stroke originalStroke = this.g.getStroke(); - this.g.setPaint(CONNECTION_COLOR); - if (connectionType.equals("association")) { - this.g.setStroke(ASSOCIATION_STROKE); - } else if (highLighted) { - this.g.setPaint(HIGHLIGHT_SequenceFlow_COLOR); - this.g.setStroke(HIGHLIGHT_FLOW_STROKE); - } - - for (int i = 1; i < xPoints.length; ++i) { - Integer sourceX = xPoints[i - 1]; - Integer sourceY = yPoints[i - 1]; - Integer targetX = xPoints[i]; - Integer targetY = yPoints[i]; - java.awt.geom.Line2D.Double line = new java.awt.geom.Line2D.Double((double) sourceX, (double) sourceY, (double) targetX, (double) targetY); - this.g.draw(line); - } - - java.awt.geom.Line2D.Double line; - if (isDefault) { - line = new java.awt.geom.Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]); - this.drawDefaultSequenceFlowIndicator(line, scaleFactor); - } - - if (conditional) { - line = new java.awt.geom.Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]); - this.drawConditionalSequenceFlowIndicator(line, scaleFactor); - } - - if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) { - line = new java.awt.geom.Line2D.Double((double) xPoints[xPoints.length - 2], (double) yPoints[xPoints.length - 2], (double) xPoints[xPoints.length - 1], (double) yPoints[xPoints.length - 1]); - this.drawArrowHead(line, scaleFactor); - } - - if (associationDirection.equals(AssociationDirection.BOTH)) { - line = new java.awt.geom.Line2D.Double((double) xPoints[1], (double) yPoints[1], (double) xPoints[0], (double) yPoints[0]); - this.drawArrowHead(line, scaleFactor); - } - - this.g.setPaint(originalPaint); - this.g.setStroke(originalStroke); - } - - /** - * 设置字体大小图标颜色 - * @param imageType - */ - @Override - public void initialize(String imageType) { - if ("png".equalsIgnoreCase(imageType)) { - this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 2); - } else { - this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 1); - } - - this.g = this.processDiagram.createGraphics(); - if (!"png".equalsIgnoreCase(imageType)) { - this.g.setBackground(new Color(255, 255, 255, 0)); - this.g.clearRect(0, 0, this.canvasWidth, this.canvasHeight); - } - - this.g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - //修改图标颜色,修改图标字体大小 - this.g.setPaint(Color.black); - Font font = new Font(this.activityFontName, 10, 14); - this.g.setFont(font); - this.fontMetrics = this.g.getFontMetrics(); - //修改连接线字体大小 - LABEL_FONT = new Font(this.labelFontName, 10, 15); - ANNOTATION_FONT = new Font(this.annotationFontName, 0, 11); - - try { - USERTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/userTask.png", this.customClassLoader)); - SCRIPTTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/scriptTask.png", this.customClassLoader)); - SERVICETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/serviceTask.png", this.customClassLoader)); - RECEIVETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/receiveTask.png", this.customClassLoader)); - SENDTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/sendTask.png", this.customClassLoader)); - MANUALTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/manualTask.png", this.customClassLoader)); - BUSINESS_RULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/businessRuleTask.png", this.customClassLoader)); - SHELL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/shellTask.png", this.customClassLoader)); - DMN_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/dmnTask.png", this.customClassLoader)); - CAMEL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/camelTask.png", this.customClassLoader)); - MULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/muleTask.png", this.customClassLoader)); - HTTP_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/httpTask.png", this.customClassLoader)); - TIMER_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/timer.png", this.customClassLoader)); - COMPENSATE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate-throw.png", this.customClassLoader)); - COMPENSATE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate.png", this.customClassLoader)); - ERROR_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error-throw.png", this.customClassLoader)); - ERROR_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error.png", this.customClassLoader)); - MESSAGE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message-throw.png", this.customClassLoader)); - MESSAGE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message.png", this.customClassLoader)); - SIGNAL_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal-throw.png", this.customClassLoader)); - SIGNAL_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal.png", this.customClassLoader)); - } catch (IOException var4) { - LOGGER.warn("Could not load image for process diagram creation: {}", var4.getMessage()); - } - - } - - /** - * 设置连接线字体 - * @param text - * @param graphicInfo - * @param centered - */ - @Override - public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) { - float interline = 1.0f; - - // text - if (text != null && text.length() > 0) { - Paint originalPaint = g.getPaint(); - Font originalFont = g.getFont(); - - g.setPaint(LABEL_COLOR); - g.setFont(LABEL_FONT); - - int wrapWidth = 100; - int textY = (int) graphicInfo.getY(); - - // TODO: use drawMultilineText() - AttributedString as = new AttributedString(text); - as.addAttribute(TextAttribute.FOREGROUND, g.getPaint()); - as.addAttribute(TextAttribute.FONT, g.getFont()); - AttributedCharacterIterator aci = as.getIterator(); - FontRenderContext frc = new FontRenderContext(null, true, false); - LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); - - while (lbm.getPosition() < text.length()) { - TextLayout tl = lbm.nextLayout(wrapWidth); - textY += tl.getAscent(); - - Rectangle2D bb = tl.getBounds(); - double tX = graphicInfo.getX(); - - if (centered) { - tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2); - } - tl.draw(g, (float) tX, textY); - textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent(); - } - - // restore originals - g.setFont(originalFont); - g.setPaint(originalPaint); - } - } - - /** - * 高亮显示task框完成的 - * @param x - * @param y - * @param width - * @param height - */ - @Override - public void drawHighLight(int x, int y, int width, int height) { - Paint originalPaint = g.getPaint(); - Stroke originalStroke = g.getStroke(); - - g.setPaint(HIGHLIGHT_COLOR); - g.setStroke(THICK_TASK_BORDER_STROKE); - - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); - g.draw(rect); - - g.setPaint(originalPaint); - g.setStroke(originalStroke); - } - - /** - * 自定义task框当前的位置 - * @param x - * @param y - * @param width - * @param height - */ - public void drawHighLightNow(int x, int y, int width, int height) { - Paint originalPaint = g.getPaint(); - Stroke originalStroke = g.getStroke(); - - g.setPaint(HIGHLIGHT_COLOR1); - g.setStroke(THICK_TASK_BORDER_STROKE); - - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); - g.draw(rect); - - g.setPaint(originalPaint); - g.setStroke(originalStroke); - } - - /** - * 自定义结束节点 - * @param x - * @param y - * @param width - * @param height - */ - public void drawHighLightEnd(int x, int y, int width, int height) { - Paint originalPaint = g.getPaint(); - Stroke originalStroke = g.getStroke(); - - g.setPaint(HIGHLIGHT_COLOR); - g.setStroke(THICK_TASK_BORDER_STROKE); - - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); - g.draw(rect); - - g.setPaint(originalPaint); - g.setStroke(originalStroke); - } - - /** - * task框自定义文字 - * @param name - * @param graphicInfo - * @param thickBorder - * @param scaleFactor - */ - @Override - protected void drawTask(String name, GraphicInfo graphicInfo, boolean thickBorder, double scaleFactor) { - - Paint originalPaint = g.getPaint(); - int x = (int) graphicInfo.getX(); - int y = (int) graphicInfo.getY(); - int width = (int) graphicInfo.getWidth(); - int height = (int) graphicInfo.getHeight(); - - // Create a new gradient paint for every task box, gradient depends on x and y and is not relative - g.setPaint(TASK_BOX_COLOR); - - int arcR = 6; - if (thickBorder) { - arcR = 3; - } - - // shape - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcR, arcR); - g.fill(rect); - g.setPaint(TASK_BORDER_COLOR); - - if (thickBorder) { - Stroke originalStroke = g.getStroke(); - g.setStroke(THICK_TASK_BORDER_STROKE); - g.draw(rect); - g.setStroke(originalStroke); - } else { - g.draw(rect); - } - - g.setPaint(originalPaint); - // text - if (scaleFactor == 1.0 && name != null && name.length() > 0) { - int boxWidth = width - (2 * TEXT_PADDING); - int boxHeight = height - 16 - ICON_PADDING - ICON_PADDING - MARKER_WIDTH - 2 - 2; - int boxX = x + width / 2 - boxWidth / 2; - int boxY = y + height / 2 - boxHeight / 2 + ICON_PADDING + ICON_PADDING - 2 - 2; - - drawMultilineCentredText(name, boxX, boxY, boxWidth, boxHeight); - } - } - - protected static Color EVENT_COLOR = new Color(255, 255, 255); - - /** - * 重写开始事件 - * @param graphicInfo - * @param image - * @param scaleFactor - */ - @Override - public void drawStartEvent(GraphicInfo graphicInfo, BufferedImage image, double scaleFactor) { - Paint originalPaint = g.getPaint(); - g.setPaint(EVENT_COLOR); - Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), - graphicInfo.getWidth(), graphicInfo.getHeight()); - g.fill(circle); - g.setPaint(EVENT_BORDER_COLOR); - g.draw(circle); - g.setPaint(originalPaint); - if (image != null) { - // calculate coordinates to center image - int imageX = (int) Math.round(graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (image.getWidth() / (2 * scaleFactor))); - int imageY = (int) Math.round(graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (image.getHeight() / (2 * scaleFactor))); - g.drawImage(image, imageX, imageY, - (int) (image.getWidth() / scaleFactor), (int) (image.getHeight() / scaleFactor), null); - } - - } - - /** - * 重写结束事件 - * @param graphicInfo - * @param scaleFactor - */ - @Override - public void drawNoneEndEvent(GraphicInfo graphicInfo, double scaleFactor) { - Paint originalPaint = g.getPaint(); - Stroke originalStroke = g.getStroke(); - g.setPaint(EVENT_COLOR); - Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), - graphicInfo.getWidth(), graphicInfo.getHeight()); - g.fill(circle); - g.setPaint(EVENT_BORDER_COLOR); -// g.setPaint(HIGHLIGHT_COLOR); - if (scaleFactor == 1.0) { - g.setStroke(END_EVENT_STROKE); - } else { - g.setStroke(new BasicStroke(2.0f)); - } - g.draw(circle); - g.setStroke(originalStroke); - g.setPaint(originalPaint); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramGenerator.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramGenerator.java deleted file mode 100644 index c17eebd4..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramGenerator.java +++ /dev/null @@ -1,404 +0,0 @@ -package com.ruoyi.flowable.flow; - - -import org.flowable.bpmn.model.Process; -import org.flowable.bpmn.model.*; -import org.flowable.image.impl.DefaultProcessDiagramCanvas; -import org.flowable.image.impl.DefaultProcessDiagramGenerator; - -import java.util.Iterator; -import java.util.List; - -/** - * @author Tony - * @date 2021/4/5 0:31 - */ -public class CustomProcessDiagramGenerator extends DefaultProcessDiagramGenerator { - @Override - protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { - this.prepareBpmnModel(bpmnModel); - DefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); - Iterator var13 = bpmnModel.getPools().iterator(); - - while (var13.hasNext()) { - Pool process = (Pool) var13.next(); - GraphicInfo subProcesses = bpmnModel.getGraphicInfo(process.getId()); - processDiagramCanvas.drawPoolOrLane(process.getName(), subProcesses, scaleFactor); - } - - var13 = bpmnModel.getProcesses().iterator(); - - Process process1; - Iterator subProcesses1; - while (var13.hasNext()) { - process1 = (Process) var13.next(); - subProcesses1 = process1.getLanes().iterator(); - - while (subProcesses1.hasNext()) { - Lane artifact = (Lane) subProcesses1.next(); - GraphicInfo subProcess = bpmnModel.getGraphicInfo(artifact.getId()); - processDiagramCanvas.drawPoolOrLane(artifact.getName(), subProcess, scaleFactor); - } - } - - var13 = bpmnModel.getProcesses().iterator(); - - while (var13.hasNext()) { - process1 = (Process) var13.next(); - subProcesses1 = process1.findFlowElementsOfType(FlowNode.class).iterator(); - - while (subProcesses1.hasNext()) { - FlowNode artifact1 = (FlowNode) subProcesses1.next(); - if (!this.isPartOfCollapsedSubProcess(artifact1, bpmnModel)) { - this.drawActivity(processDiagramCanvas, bpmnModel, artifact1, highLightedActivities, highLightedFlows, scaleFactor, Boolean.valueOf(drawSequenceFlowNameWithNoLabelDI)); - } - } - } - - var13 = bpmnModel.getProcesses().iterator(); - - label75: - while (true) { - List subProcesses2; - do { - if (!var13.hasNext()) { - return processDiagramCanvas; - } - - process1 = (Process) var13.next(); - subProcesses1 = process1.getArtifacts().iterator(); - - while (subProcesses1.hasNext()) { - Artifact artifact2 = (Artifact) subProcesses1.next(); - this.drawArtifact(processDiagramCanvas, bpmnModel, artifact2); - } - - subProcesses2 = process1.findFlowElementsOfType(SubProcess.class, true); - } while (subProcesses2 == null); - - Iterator artifact3 = subProcesses2.iterator(); - - while (true) { - GraphicInfo graphicInfo; - SubProcess subProcess1; - do { - do { - if (!artifact3.hasNext()) { - continue label75; - } - - subProcess1 = (SubProcess) artifact3.next(); - graphicInfo = bpmnModel.getGraphicInfo(subProcess1.getId()); - } while (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded().booleanValue()); - } while (this.isPartOfCollapsedSubProcess(subProcess1, bpmnModel)); - - Iterator var19 = subProcess1.getArtifacts().iterator(); - - while (var19.hasNext()) { - Artifact subProcessArtifact = (Artifact) var19.next(); - this.drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact); - } - } - } - } - - protected static DefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) { - double minX = 1.7976931348623157E308D; - double maxX = 0.0D; - double minY = 1.7976931348623157E308D; - double maxY = 0.0D; - - GraphicInfo nrOfLanes; - for (Iterator flowNodes = bpmnModel.getPools().iterator(); flowNodes.hasNext(); maxY = nrOfLanes.getY() + nrOfLanes.getHeight()) { - Pool artifacts = (Pool) flowNodes.next(); - nrOfLanes = bpmnModel.getGraphicInfo(artifacts.getId()); - minX = nrOfLanes.getX(); - maxX = nrOfLanes.getX() + nrOfLanes.getWidth(); - minY = nrOfLanes.getY(); - } - - List var23 = gatherAllFlowNodes(bpmnModel); - Iterator var24 = var23.iterator(); - - label155: - while (var24.hasNext()) { - FlowNode var26 = (FlowNode) var24.next(); - GraphicInfo artifact = bpmnModel.getGraphicInfo(var26.getId()); - if (artifact.getX() + artifact.getWidth() > maxX) { - maxX = artifact.getX() + artifact.getWidth(); - } - - if (artifact.getX() < minX) { - minX = artifact.getX(); - } - - if (artifact.getY() + artifact.getHeight() > maxY) { - maxY = artifact.getY() + artifact.getHeight(); - } - - if (artifact.getY() < minY) { - minY = artifact.getY(); - } - - Iterator process = var26.getOutgoingFlows().iterator(); - - while (true) { - List l; - do { - if (!process.hasNext()) { - continue label155; - } - - SequenceFlow graphicInfoList = (SequenceFlow) process.next(); - l = bpmnModel.getFlowLocationGraphicInfo(graphicInfoList.getId()); - } while (l == null); - - Iterator graphicInfo = l.iterator(); - - while (graphicInfo.hasNext()) { - GraphicInfo graphicInfo1 = (GraphicInfo) graphicInfo.next(); - if (graphicInfo1.getX() > maxX) { - maxX = graphicInfo1.getX(); - } - - if (graphicInfo1.getX() < minX) { - minX = graphicInfo1.getX(); - } - - if (graphicInfo1.getY() > maxY) { - maxY = graphicInfo1.getY(); - } - - if (graphicInfo1.getY() < minY) { - minY = graphicInfo1.getY(); - } - } - } - } - - List var25 = gatherAllArtifacts(bpmnModel); - Iterator var27 = var25.iterator(); - - GraphicInfo var37; - while (var27.hasNext()) { - Artifact var29 = (Artifact) var27.next(); - GraphicInfo var31 = bpmnModel.getGraphicInfo(var29.getId()); - if (var31 != null) { - if (var31.getX() + var31.getWidth() > maxX) { - maxX = var31.getX() + var31.getWidth(); - } - - if (var31.getX() < minX) { - minX = var31.getX(); - } - - if (var31.getY() + var31.getHeight() > maxY) { - maxY = var31.getY() + var31.getHeight(); - } - - if (var31.getY() < minY) { - minY = var31.getY(); - } - } - - List var33 = bpmnModel.getFlowLocationGraphicInfo(var29.getId()); - if (var33 != null) { - Iterator var35 = var33.iterator(); - - while (var35.hasNext()) { - var37 = (GraphicInfo) var35.next(); - if (var37.getX() > maxX) { - maxX = var37.getX(); - } - - if (var37.getX() < minX) { - minX = var37.getX(); - } - - if (var37.getY() > maxY) { - maxY = var37.getY(); - } - - if (var37.getY() < minY) { - minY = var37.getY(); - } - } - } - } - - int var28 = 0; - Iterator var30 = bpmnModel.getProcesses().iterator(); - - while (var30.hasNext()) { - Process var32 = (Process) var30.next(); - Iterator var34 = var32.getLanes().iterator(); - - while (var34.hasNext()) { - Lane var36 = (Lane) var34.next(); - ++var28; - var37 = bpmnModel.getGraphicInfo(var36.getId()); - if (var37.getX() + var37.getWidth() > maxX) { - maxX = var37.getX() + var37.getWidth(); - } - - if (var37.getX() < minX) { - minX = var37.getX(); - } - - if (var37.getY() + var37.getHeight() > maxY) { - maxY = var37.getY() + var37.getHeight(); - } - - if (var37.getY() < minY) { - minY = var37.getY(); - } - } - } - - if (var23.isEmpty() && bpmnModel.getPools().isEmpty() && var28 == 0) { - minX = 0.0D; - minY = 0.0D; - } - - return new CustomProcessDiagramCanvas((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); - } - - - private static void drawHighLight(DefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { - processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight()); - - } - - private static void drawHighLightNow(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { - processDiagramCanvas.drawHighLightNow((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight()); - - } - - private static void drawHighLightEnd(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { - processDiagramCanvas.drawHighLightEnd((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight()); - - } - - @Override - protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, - FlowNode flowNode, java.util.List highLightedActivities, java.util.List highLightedFlows, double scaleFactor, Boolean drawSequenceFlowNameWithNoLabelDI) { - - DefaultProcessDiagramGenerator.ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass()); - if (drawInstruction != null) { - - drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode); - - // Gather info on the multi instance marker - boolean multiInstanceSequential = false; - boolean multiInstanceParallel = false; - boolean collapsed = false; - if (flowNode instanceof Activity) { - Activity activity = (Activity) flowNode; - MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics(); - if (multiInstanceLoopCharacteristics != null) { - multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential(); - multiInstanceParallel = !multiInstanceSequential; - } - } - - // Gather info on the collapsed marker - GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); - if (flowNode instanceof SubProcess) { - collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded(); - } else if (flowNode instanceof CallActivity) { - collapsed = true; - } - - if (scaleFactor == 1.0) { - // Actually draw the markers - processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), - multiInstanceSequential, multiInstanceParallel, collapsed); - } - - // Draw highlighted activities - if (highLightedActivities.contains(flowNode.getId())) { - - if (highLightedActivities.get(highLightedActivities.size() - 1).equals(flowNode.getId()) - && !"endenv".equals(flowNode.getId())) { - if ((flowNode.getId().contains("Event_"))) { - drawHighLightEnd((CustomProcessDiagramCanvas) processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); - } else { - drawHighLightNow((CustomProcessDiagramCanvas) processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); - } - } else { - drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); - } - - - } - - } - - // Outgoing transitions of activity - for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) { - boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId())); - String defaultFlow = null; - if (flowNode instanceof Activity) { - defaultFlow = ((Activity) flowNode).getDefaultFlow(); - } else if (flowNode instanceof Gateway) { - defaultFlow = ((Gateway) flowNode).getDefaultFlow(); - } - - boolean isDefault = false; - if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) { - isDefault = true; - } - boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway); - - String sourceRef = sequenceFlow.getSourceRef(); - String targetRef = sequenceFlow.getTargetRef(); - FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef); - FlowElement targetElement = bpmnModel.getFlowElement(targetRef); - java.util.List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId()); - if (graphicInfoList != null && graphicInfoList.size() > 0) { - graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList); - int xPoints[] = new int[graphicInfoList.size()]; - int yPoints[] = new int[graphicInfoList.size()]; - - for (int i = 1; i < graphicInfoList.size(); i++) { - GraphicInfo graphicInfo = graphicInfoList.get(i); - GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1); - - if (i == 1) { - xPoints[0] = (int) previousGraphicInfo.getX(); - yPoints[0] = (int) previousGraphicInfo.getY(); - } - xPoints[i] = (int) graphicInfo.getX(); - yPoints[i] = (int) graphicInfo.getY(); - - } - - processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor); - - - // Draw sequenceflow label - GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId()); - if (labelGraphicInfo != null) { - processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false); - } else { - if (drawSequenceFlowNameWithNoLabelDI) { - GraphicInfo lineCenter = getLineCenter(graphicInfoList); - processDiagramCanvas.drawLabel(sequenceFlow.getName(), lineCenter, false); - } - - } - } - } - - // Nested elements - if (flowNode instanceof FlowElementsContainer) { - for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) { - if (nestedFlowElement instanceof FlowNode && !isPartOfCollapsedSubProcess(nestedFlowElement, bpmnModel)) { - drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, - highLightedActivities, highLightedFlows, scaleFactor, drawSequenceFlowNameWithNoLabelDI); - } - } - } - } -} - diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FindNextNodeUtil.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FindNextNodeUtil.java deleted file mode 100644 index b367bd72..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FindNextNodeUtil.java +++ /dev/null @@ -1,266 +0,0 @@ -package com.ruoyi.flowable.flow; - -import com.googlecode.aviator.AviatorEvaluator; -import com.googlecode.aviator.Expression; -//import com.greenpineyu.fel.FelEngine; -//import com.greenpineyu.fel.FelEngineImpl; -//import com.greenpineyu.fel.context.FelContext; -//import org.apache.commons.jexl2.JexlContext; -//import org.apache.commons.jexl2.JexlEngine; -//import org.apache.commons.jexl2.MapContext; -//import org.apache.commons.lang3.StringUtils; -import org.flowable.bpmn.model.Process; -import org.flowable.bpmn.model.*; -import org.flowable.engine.RepositoryService; -import org.flowable.engine.repository.ProcessDefinition; - -import java.util.*; - -/** - * @author Tony - * @date 2021/4/19 20:51 - */ -public class FindNextNodeUtil { - - /** - * 获取下一步骤的用户任务 - * - * @param repositoryService - * @param map - * @return - */ - public static List getNextUserTasks(RepositoryService repositoryService, org.flowable.task.api.Task task, Map map) { - List data = new ArrayList<>(); - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); - Process mainProcess = bpmnModel.getMainProcess(); - Collection flowElements = mainProcess.getFlowElements(); - String key = task.getTaskDefinitionKey(); - FlowElement flowElement = bpmnModel.getFlowElement(key); - next(flowElements, flowElement, map, data); - return data; - } - - /** - * 启动流程时获取下一步骤的用户任务 - * - * @param repositoryService - * @param map - * @return - */ - public static List getNextUserTasksByStart(RepositoryService repositoryService, ProcessDefinition processDefinition, Map map) { - List data = new ArrayList<>(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); - Process mainProcess = bpmnModel.getMainProcess(); - Collection flowElements = mainProcess.getFlowElements(); - String key = null; - // 找到开始节点 并获取唯一key - for (FlowElement flowElement : flowElements) { - if (flowElement instanceof StartEvent) { - key = flowElement.getId(); - break; - } - } - FlowElement flowElement = bpmnModel.getFlowElement(key); - List sequenceFlows = ((StartEvent)flowElement).getOutgoingFlows(); - // 获取出口连线, 此时从开始节点往后,只能是一个出口 - if (!sequenceFlows.isEmpty()) { - SequenceFlow sequenceFlow = sequenceFlows.get(0); - FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement(); - next(flowElements, targetFlowElement, map, data); - } - return data; - } - - - /** - * 查找下一节点 - * - * @param flowElements - * @param flowElement - * @param map - * @param nextUser - */ - public static void next(Collection flowElements, FlowElement flowElement, Map map, List nextUser) { - //如果是结束节点 - if (flowElement instanceof EndEvent) { - //如果是子任务的结束节点 - if (getSubProcess(flowElements, flowElement) != null) { - flowElement = getSubProcess(flowElements, flowElement); - } - } - //获取Task的出线信息--可以拥有多个 - List outGoingFlows = null; - if (flowElement instanceof Task) { - outGoingFlows = ((Task) flowElement).getOutgoingFlows(); - } else if (flowElement instanceof Gateway) { - outGoingFlows = ((Gateway) flowElement).getOutgoingFlows(); - } else if (flowElement instanceof StartEvent) { - outGoingFlows = ((StartEvent) flowElement).getOutgoingFlows(); - } else if (flowElement instanceof SubProcess) { - outGoingFlows = ((SubProcess) flowElement).getOutgoingFlows(); - } else if (flowElement instanceof CallActivity) { - outGoingFlows = ((CallActivity) flowElement).getOutgoingFlows(); - } - if (outGoingFlows != null && outGoingFlows.size() > 0) { - //遍历所有的出线--找到可以正确执行的那一条 - for (SequenceFlow sequenceFlow : outGoingFlows) { - //1.有表达式,且为true - //2.无表达式 - String expression = sequenceFlow.getConditionExpression(); - if (expression == null || - expressionResult(map, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))) { - //出线的下一节点 - String nextFlowElementID = sequenceFlow.getTargetRef(); - if (checkSubProcess(nextFlowElementID, flowElements, nextUser)) { - continue; - } - - //查询下一节点的信息 - FlowElement nextFlowElement = getFlowElementById(nextFlowElementID, flowElements); - //调用流程 - if (nextFlowElement instanceof CallActivity) { - CallActivity ca = (CallActivity) nextFlowElement; - if (ca.getLoopCharacteristics() != null) { - UserTask userTask = new UserTask(); - userTask.setId(ca.getId()); - - userTask.setId(ca.getId()); - userTask.setLoopCharacteristics(ca.getLoopCharacteristics()); - userTask.setName(ca.getName()); - nextUser.add(userTask); - } - next(flowElements, nextFlowElement, map, nextUser); - } - //用户任务 - if (nextFlowElement instanceof UserTask) { - nextUser.add((UserTask) nextFlowElement); - } - //排他网关 - else if (nextFlowElement instanceof ExclusiveGateway) { - next(flowElements, nextFlowElement, map, nextUser); - } - //并行网关 - else if (nextFlowElement instanceof ParallelGateway) { - next(flowElements, nextFlowElement, map, nextUser); - } - //接收任务 - else if (nextFlowElement instanceof ReceiveTask) { - next(flowElements, nextFlowElement, map, nextUser); - } - //服务任务 - else if (nextFlowElement instanceof ServiceTask) { - next(flowElements, nextFlowElement, map, nextUser); - } - //子任务的起点 - else if (nextFlowElement instanceof StartEvent) { - next(flowElements, nextFlowElement, map, nextUser); - } - //结束节点 - else if (nextFlowElement instanceof EndEvent) { - next(flowElements, nextFlowElement, map, nextUser); - } - } - } - } - } - - /** - * 判断是否是多实例子流程并且需要设置集合类型变量 - */ - public static boolean checkSubProcess(String id, Collection flowElements, List nextUser) { - for (FlowElement flowElement1 : flowElements) { - if (flowElement1 instanceof SubProcess && flowElement1.getId().equals(id)) { - - SubProcess sp = (SubProcess) flowElement1; - if (sp.getLoopCharacteristics() != null) { -// String inputDataItem = sp.getLoopCharacteristics().getInputDataItem(); - UserTask userTask = new UserTask(); - userTask.setId(sp.getId()); - userTask.setLoopCharacteristics(sp.getLoopCharacteristics()); - userTask.setName(sp.getName()); - nextUser.add(userTask); - return true; - } - } - } - - return false; - - } - - /** - * 查询一个节点的是否子任务中的节点,如果是,返回子任务 - * - * @param flowElements 全流程的节点集合 - * @param flowElement 当前节点 - * @return - */ - public static FlowElement getSubProcess(Collection flowElements, FlowElement flowElement) { - for (FlowElement flowElement1 : flowElements) { - if (flowElement1 instanceof SubProcess) { - for (FlowElement flowElement2 : ((SubProcess) flowElement1).getFlowElements()) { - if (flowElement.equals(flowElement2)) { - return flowElement1; - } - } - } - } - return null; - } - - - /** - * 根据ID查询流程节点对象, 如果是子任务,则返回子任务的开始节点 - * - * @param Id 节点ID - * @param flowElements 流程节点集合 - * @return - */ - public static FlowElement getFlowElementById(String Id, Collection flowElements) { - for (FlowElement flowElement : flowElements) { - if (flowElement.getId().equals(Id)) { - //如果是子任务,则查询出子任务的开始节点 - if (flowElement instanceof SubProcess) { - return getStartFlowElement(((SubProcess) flowElement).getFlowElements()); - } - return flowElement; - } - if (flowElement instanceof SubProcess) { - FlowElement flowElement1 = getFlowElementById(Id, ((SubProcess) flowElement).getFlowElements()); - if (flowElement1 != null) { - return flowElement1; - } - } - } - return null; - } - - /** - * 返回流程的开始节点 - * - * @param flowElements 节点集合 - * @description: - */ - public static FlowElement getStartFlowElement(Collection flowElements) { - for (FlowElement flowElement : flowElements) { - if (flowElement instanceof StartEvent) { - return flowElement; - } - } - return null; - } - - /** - * 校验el表达式 - * - * @param map - * @param expression - * @return - */ - public static boolean expressionResult(Map map, String expression) { - Expression exp = AviatorEvaluator.compile(expression); - return (Boolean) exp.execute(map); -// return true; - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FlowableUtils.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FlowableUtils.java deleted file mode 100644 index ce9e2566..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/FlowableUtils.java +++ /dev/null @@ -1,702 +0,0 @@ -package com.ruoyi.flowable.flow; - -import lombok.extern.slf4j.Slf4j; -import org.flowable.bpmn.model.*; -import org.flowable.engine.RepositoryService; -import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; -import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; -import org.flowable.engine.repository.ProcessDefinition; -import org.flowable.task.api.history.HistoricTaskInstance; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @author Tony - * @date 2021-04-03 23:57 - */ -@Slf4j -public class FlowableUtils { - - /** - * 根据节点,获取入口连线 - * - * @param source - * @return - */ - public static List getElementIncomingFlows(FlowElement source) { - List sequenceFlows = null; - if (source instanceof FlowNode) { - sequenceFlows = ((FlowNode) source).getIncomingFlows(); - } else if (source instanceof Gateway) { - sequenceFlows = ((Gateway) source).getIncomingFlows(); - } else if (source instanceof SubProcess) { - sequenceFlows = ((SubProcess) source).getIncomingFlows(); - } else if (source instanceof StartEvent) { - sequenceFlows = ((StartEvent) source).getIncomingFlows(); - } else if (source instanceof EndEvent) { - sequenceFlows = ((EndEvent) source).getIncomingFlows(); - } - return sequenceFlows; - } - - /** - * 根据节点,获取出口连线 - * - * @param source - * @return - */ - public static List getElementOutgoingFlows(FlowElement source) { - List sequenceFlows = null; - if (source instanceof FlowNode) { - sequenceFlows = ((FlowNode) source).getOutgoingFlows(); - } else if (source instanceof Gateway) { - sequenceFlows = ((Gateway) source).getOutgoingFlows(); - } else if (source instanceof SubProcess) { - sequenceFlows = ((SubProcess) source).getOutgoingFlows(); - } else if (source instanceof StartEvent) { - sequenceFlows = ((StartEvent) source).getOutgoingFlows(); - } else if (source instanceof EndEvent) { - sequenceFlows = ((EndEvent) source).getOutgoingFlows(); - } - return sequenceFlows; - } - - /** - * 获取全部节点列表,包含子流程节点 - * - * @param flowElements - * @param allElements - * @return - */ - public static Collection getAllElements(Collection flowElements, Collection allElements) { - allElements = allElements == null ? new ArrayList<>() : allElements; - - for (FlowElement flowElement : flowElements) { - allElements.add(flowElement); - if (flowElement instanceof SubProcess) { - // 继续深入子流程,进一步获取子流程 - allElements = FlowableUtils.getAllElements(((SubProcess) flowElement).getFlowElements(), allElements); - } - } - return allElements; - } - - /** - * 迭代获取父级任务节点列表,向前找 - * - * @param source 起始节点 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param userTaskList 已找到的用户任务节点 - * @return - */ - public static List iteratorFindParentUserTasks(FlowElement source, Set hasSequenceFlow, List userTaskList) { - userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (source instanceof StartEvent && source.getSubProcess() != null) { - userTaskList = iteratorFindParentUserTasks(source.getSubProcess(), hasSequenceFlow, userTaskList); - } - - // 根据类型,获取入口连线 - List sequenceFlows = getElementIncomingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 类型为用户节点,则新增父级节点 - if (sequenceFlow.getSourceFlowElement() instanceof UserTask) { - userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement()); - continue; - } - // 类型为子流程,则添加子流程开始节点出口处相连的节点 - if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) { - // 获取子流程用户任务节点 - List childUserTaskList = findChildProcessUserTasks((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null); - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续 - if (childUserTaskList != null && childUserTaskList.size() > 0) { - userTaskList.addAll(childUserTaskList); - continue; - } - } - // 继续迭代 - userTaskList = iteratorFindParentUserTasks(sequenceFlow.getSourceFlowElement(), hasSequenceFlow, userTaskList); - } - } - return userTaskList; - } - - /** - * 根据正在运行的任务节点,迭代获取子级任务节点列表,向后找 - * - * @param source 起始节点(退回节点) - * @param runTaskKeyList 正在运行的任务 Key,用于校验任务节点是否是正在运行的节点 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param userTaskList 需要撤回的用户任务列表 - * @return - */ - public static List iteratorFindChildUserTasks(FlowElement source, List runTaskKeyList, Set hasSequenceFlow, List userTaskList) { - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; - - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (source instanceof EndEvent && source.getSubProcess() != null) { - userTaskList = iteratorFindChildUserTasks(source.getSubProcess(), runTaskKeyList, hasSequenceFlow, userTaskList); - } - - // 根据类型,获取出口连线 - List sequenceFlows = getElementOutgoingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加 - if (sequenceFlow.getTargetFlowElement() instanceof UserTask && runTaskKeyList.contains((sequenceFlow.getTargetFlowElement()).getId())) { - userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement()); - continue; - } - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取 - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { - List childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runTaskKeyList, hasSequenceFlow, null); - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续 - if (childUserTaskList != null && childUserTaskList.size() > 0) { - userTaskList.addAll(childUserTaskList); - continue; - } - } - // 继续迭代 - userTaskList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, hasSequenceFlow, userTaskList); - } - } - return userTaskList; - } - - /** - * 迭代获取子流程用户任务节点 - * - * @param source 起始节点 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param userTaskList 需要撤回的用户任务列表 - * @return - */ - public static List findChildProcessUserTasks(FlowElement source, Set hasSequenceFlow, List userTaskList) { - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; - - // 根据类型,获取出口连线 - List sequenceFlows = getElementOutgoingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加 - if (sequenceFlow.getTargetFlowElement() instanceof UserTask) { - userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement()); - continue; - } - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取 - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { - List childUserTaskList = findChildProcessUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null); - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续 - if (childUserTaskList != null && childUserTaskList.size() > 0) { - userTaskList.addAll(childUserTaskList); - continue; - } - } - // 继续迭代 - userTaskList = findChildProcessUserTasks(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, userTaskList); - } - } - return userTaskList; - } - - /** - * 从后向前寻路,获取所有脏线路上的点 - * - * @param source 起始节点 - * @param passRoads 已经经过的点集合 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param targets 目标脏线路终点 - * @param dirtyRoads 确定为脏数据的点,因为不需要重复,因此使用 set 存储 - * @return - */ - public static Set iteratorFindDirtyRoads(FlowElement source, List passRoads, Set hasSequenceFlow, List targets, Set dirtyRoads) { - passRoads = passRoads == null ? new ArrayList<>() : passRoads; - dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads; - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (source instanceof StartEvent && source.getSubProcess() != null) { - dirtyRoads = iteratorFindDirtyRoads(source.getSubProcess(), passRoads, hasSequenceFlow, targets, dirtyRoads); - } - - // 根据类型,获取入口连线 - List sequenceFlows = getElementIncomingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 新增经过的路线 - passRoads.add(sequenceFlow.getSourceFlowElement().getId()); - // 如果此点为目标点,确定经过的路线为脏线路,添加点到脏线路中,然后找下个连线 - if (targets.contains(sequenceFlow.getSourceFlowElement().getId())) { - dirtyRoads.addAll(passRoads); - continue; - } - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) { - dirtyRoads = findChildProcessAllDirtyRoad((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, dirtyRoads); - // 是否存在子流程上,true 是,false 否 - Boolean isInChildProcess = dirtyTargetInChildProcess((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, targets, null); - if (isInChildProcess) { - // 已在子流程上找到,该路线结束 - continue; - } - } - // 继续迭代 - dirtyRoads = iteratorFindDirtyRoads(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, targets, dirtyRoads); - } - } - return dirtyRoads; - } - - /** - * 迭代获取子流程脏路线 - * 说明,假如回退的点就是子流程,那么也肯定会回退到子流程最初的用户任务节点,因此子流程中的节点全是脏路线 - * - * @param source 起始节点 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param dirtyRoads 确定为脏数据的点,因为不需要重复,因此使用 set 存储 - * @return - */ - public static Set findChildProcessAllDirtyRoad(FlowElement source, Set hasSequenceFlow, Set dirtyRoads) { - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads; - - // 根据类型,获取出口连线 - List sequenceFlows = getElementOutgoingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 添加脏路线 - dirtyRoads.add(sequenceFlow.getTargetFlowElement().getId()); - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取 - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { - dirtyRoads = findChildProcessAllDirtyRoad((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, dirtyRoads); - } - // 继续迭代 - dirtyRoads = findChildProcessAllDirtyRoad(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, dirtyRoads); - } - } - return dirtyRoads; - } - - /** - * 判断脏路线结束节点是否在子流程上 - * - * @param source 起始节点 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param targets 判断脏路线节点是否存在子流程上,只要存在一个,说明脏路线只到子流程为止 - * @param inChildProcess 是否存在子流程上,true 是,false 否 - * @return - */ - public static Boolean dirtyTargetInChildProcess(FlowElement source, Set hasSequenceFlow, List targets, Boolean inChildProcess) { - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - inChildProcess = inChildProcess != null && inChildProcess; - - // 根据类型,获取出口连线 - List sequenceFlows = getElementOutgoingFlows(source); - - if (sequenceFlows != null && !inChildProcess) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 如果发现目标点在子流程上存在,说明只到子流程为止 - if (targets.contains(sequenceFlow.getTargetFlowElement().getId())) { - inChildProcess = true; - break; - } - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取 - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { - inChildProcess = dirtyTargetInChildProcess((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, targets, inChildProcess); - } - // 继续迭代 - inChildProcess = dirtyTargetInChildProcess(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, targets, inChildProcess); - } - } - return inChildProcess; - } - - /** - * 迭代从后向前扫描,判断目标节点相对于当前节点是否是串行 - * 不存在直接回退到子流程中的情况,但存在从子流程出去到父流程情况 - * - * @param source 起始节点 - * @param isSequential 是否串行 - * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复 - * @param targetKsy 目标节点 - * @return - */ - public static Boolean iteratorCheckSequentialReferTarget(FlowElement source, String targetKsy, Set hasSequenceFlow, Boolean isSequential) { - isSequential = isSequential == null || isSequential; - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (source instanceof StartEvent && source.getSubProcess() != null) { - isSequential = iteratorCheckSequentialReferTarget(source.getSubProcess(), targetKsy, hasSequenceFlow, isSequential); - } - - // 根据类型,获取入口连线 - List sequenceFlows = getElementIncomingFlows(source); - - if (sequenceFlows != null) { - // 循环找到目标元素 - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 如果目标节点已被判断为并行,后面都不需要执行,直接返回 - if (!isSequential) { - break; - } - // 这条线路存在目标节点,这条线路完成,进入下个线路 - if (targetKsy.equals(sequenceFlow.getSourceFlowElement().getId())) { - continue; - } - if (sequenceFlow.getSourceFlowElement() instanceof StartEvent) { - isSequential = false; - break; - } - // 否则就继续迭代 - isSequential = iteratorCheckSequentialReferTarget(sequenceFlow.getSourceFlowElement(), targetKsy, hasSequenceFlow, isSequential); - } - } - return isSequential; - } - - /** - * 从后向前寻路,获取到达节点的所有路线 - * 不存在直接回退到子流程,但是存在回退到父级流程的情况 - * - * @param source 起始节点 - * @param passRoads 已经经过的点集合 - * @param roads 路线 - * @return - */ - public static List> findRoad(FlowElement source, List passRoads, Set hasSequenceFlow, List> roads) { - passRoads = passRoads == null ? new ArrayList<>() : passRoads; - roads = roads == null ? new ArrayList<>() : roads; - hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; - - // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代 - if (source instanceof StartEvent && source.getSubProcess() != null) { - roads = findRoad(source.getSubProcess(), passRoads, hasSequenceFlow, roads); - } - - // 根据类型,获取入口连线 - List sequenceFlows = getElementIncomingFlows(source); - - if (sequenceFlows != null && sequenceFlows.size() != 0) { - for (SequenceFlow sequenceFlow : sequenceFlows) { - // 如果发现连线重复,说明循环了,跳过这个循环 - if (hasSequenceFlow.contains(sequenceFlow.getId())) { - continue; - } - // 添加已经走过的连线 - hasSequenceFlow.add(sequenceFlow.getId()); - // 添加经过路线 - if (sequenceFlow.getSourceFlowElement() instanceof UserTask) { - passRoads.add((UserTask) sequenceFlow.getSourceFlowElement()); - } - // 继续迭代 - roads = findRoad(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, roads); - } - } else { - // 添加路线 - roads.add(passRoads); - } - return roads; - } - - /** - * 历史节点数据清洗,清洗掉又回滚导致的脏数据 - * - * @param allElements 全部节点信息 - * @param historicTaskInstanceList 历史任务实例信息,数据采用开始时间升序 - * @return - */ - public static List historicTaskInstanceClean(Collection allElements, List historicTaskInstanceList) { - // 会签节点收集 - List multiTask = new ArrayList<>(); - allElements.forEach(flowElement -> { - if (flowElement instanceof UserTask) { - // 如果该节点的行为为会签行为,说明该节点为会签节点 - if (((UserTask) flowElement).getBehavior() instanceof ParallelMultiInstanceBehavior || ((UserTask) flowElement).getBehavior() instanceof SequentialMultiInstanceBehavior) { - multiTask.add(flowElement.getId()); - } - } - }); - // 循环放入栈,栈 LIFO:后进先出 - Stack stack = new Stack<>(); - historicTaskInstanceList.forEach(stack::push); - // 清洗后的历史任务实例 - List lastHistoricTaskInstanceList = new ArrayList<>(); - // 网关存在可能只走了部分分支情况,且还存在跳转废弃数据以及其他分支数据的干扰,因此需要对历史节点数据进行清洗 - // 临时用户任务 key - StringBuilder userTaskKey = null; - // 临时被删掉的任务 key,存在并行情况 - List deleteKeyList = new ArrayList<>(); - // 临时脏数据线路 - List> dirtyDataLineList = new ArrayList<>(); - // 由某个点跳到会签点,此时出现多个会签实例对应 1 个跳转情况,需要把这些连续脏数据都找到 - // 会签特殊处理下标 - int multiIndex = -1; - // 会签特殊处理 key - StringBuilder multiKey = null; - // 会签特殊处理操作标识 - boolean multiOpera = false; - while (!stack.empty()) { - // 从这里开始 userTaskKey 都还是上个栈的 key - // 是否是脏数据线路上的点 - final boolean[] isDirtyData = {false}; - for (Set oldDirtyDataLine : dirtyDataLineList) { - if (oldDirtyDataLine.contains(stack.peek().getTaskDefinitionKey())) { - isDirtyData[0] = true; - } - } - // 删除原因不为空,说明从这条数据开始回跳或者回退的 - // MI_END:会签完成后,其他未签到节点的删除原因,不在处理范围内 - if (stack.peek().getDeleteReason() != null && !"MI_END".equals(stack.peek().getDeleteReason())) { - // 可以理解为脏线路起点 - String dirtyPoint = ""; - if (stack.peek().getDeleteReason().contains("Change activity to ")) { - dirtyPoint = stack.peek().getDeleteReason().replace("Change activity to ", ""); - } - // 会签回退删除原因有点不同 - if (stack.peek().getDeleteReason().contains("Change parent activity to ")) { - dirtyPoint = stack.peek().getDeleteReason().replace("Change parent activity to ", ""); - } - FlowElement dirtyTask = null; - // 获取变更节点的对应的入口处连线 - // 如果是网关并行回退情况,会变成两条脏数据路线,效果一样 - for (FlowElement flowElement : allElements) { - if (flowElement.getId().equals(stack.peek().getTaskDefinitionKey())) { - dirtyTask = flowElement; - } - } - // 获取脏数据线路 - Set dirtyDataLine = FlowableUtils.iteratorFindDirtyRoads(dirtyTask, null, null, Arrays.asList(dirtyPoint.split(",")), null); - // 自己本身也是脏线路上的点,加进去 - dirtyDataLine.add(stack.peek().getTaskDefinitionKey()); - log.info(stack.peek().getTaskDefinitionKey() + "点脏路线集合:" + dirtyDataLine); - // 是全新的需要添加的脏线路 - boolean isNewDirtyData = true; - for (int i = 0; i < dirtyDataLineList.size(); i++) { - // 如果发现他的上个节点在脏线路内,说明这个点可能是并行的节点,或者连续驳回 - // 这时,都以之前的脏线路节点为标准,只需合并脏线路即可,也就是路线补全 - if (dirtyDataLineList.get(i).contains(userTaskKey.toString())) { - isNewDirtyData = false; - dirtyDataLineList.get(i).addAll(dirtyDataLine); - } - } - // 已确定时全新的脏线路 - if (isNewDirtyData) { - // deleteKey 单一路线驳回到并行,这种同时生成多个新实例记录情况,这时 deleteKey 其实是由多个值组成 - // 按照逻辑,回退后立刻生成的实例记录就是回退的记录 - // 至于驳回所生成的 Key,直接从删除原因中获取,因为存在驳回到并行的情况 - deleteKeyList.add(dirtyPoint + ","); - dirtyDataLineList.add(dirtyDataLine); - } - // 添加后,现在这个点变成脏线路上的点了 - isDirtyData[0] = true; - } - // 如果不是脏线路上的点,说明是有效数据,添加历史实例 Key - if (!isDirtyData[0]) { - lastHistoricTaskInstanceList.add(stack.peek().getTaskDefinitionKey()); - } - // 校验脏线路是否结束 - for (int i = 0; i < deleteKeyList.size(); i++) { - // 如果发现脏数据属于会签,记录下下标与对应 Key,以备后续比对,会签脏数据范畴开始 - if (multiKey == null && multiTask.contains(stack.peek().getTaskDefinitionKey()) - && deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) { - multiIndex = i; - multiKey = new StringBuilder(stack.peek().getTaskDefinitionKey()); - } - // 会签脏数据处理,节点退回会签清空 - // 如果在会签脏数据范畴中发现 Key改变,说明会签脏数据在上个节点就结束了,可以把会签脏数据删掉 - if (multiKey != null && !multiKey.toString().equals(stack.peek().getTaskDefinitionKey())) { - deleteKeyList.set(multiIndex, deleteKeyList.get(multiIndex).replace(stack.peek().getTaskDefinitionKey() + ",", "")); - multiKey = null; - // 结束进行下校验删除 - multiOpera = true; - } - // 其他脏数据处理 - // 发现该路线最后一条脏数据,说明这条脏数据线路处理完了,删除脏数据信息 - // 脏数据产生的新实例中是否包含这条数据 - if (multiKey == null && deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) { - // 删除匹配到的部分 - deleteKeyList.set(i, deleteKeyList.get(i).replace(stack.peek().getTaskDefinitionKey() + ",", "")); - } - // 如果每组中的元素都以匹配过,说明脏数据结束 - if ("".equals(deleteKeyList.get(i))) { - // 同时删除脏数据 - deleteKeyList.remove(i); - dirtyDataLineList.remove(i); - break; - } - } - // 会签数据处理需要在循环外处理,否则可能导致溢出 - // 会签的数据肯定是之前放进去的所以理论上不会溢出,但还是校验下 - if (multiOpera && deleteKeyList.size() > multiIndex && "".equals(deleteKeyList.get(multiIndex))) { - // 同时删除脏数据 - deleteKeyList.remove(multiIndex); - dirtyDataLineList.remove(multiIndex); - multiIndex = -1; - multiOpera = false; - } - // pop() 方法与 peek() 方法不同,在返回值的同时,会把值从栈中移除 - // 保存新的 userTaskKey 在下个循环中使用 - userTaskKey = new StringBuilder(stack.pop().getTaskDefinitionKey()); - } - log.info("清洗后的历史节点数据:" + lastHistoricTaskInstanceList); - return lastHistoricTaskInstanceList; - } - - /** - * 从 flowElement 获取 指定名称的 拓展元素 - * - * @param flowElement 元素 - * @param extensionElementName 拓展元素名称 - */ - public static ExtensionElement getExtensionElementFromFlowElementByName(FlowElement flowElement, String extensionElementName) { - - if (flowElement == null) { - return null; - } - Map> extensionElements = flowElement.getExtensionElements(); - for (Map.Entry> stringEntry : extensionElements.entrySet()) { - if (stringEntry.getKey().equals(extensionElementName)) { - for (ExtensionElement extensionElement : stringEntry.getValue()) { - if (extensionElement.getName().equals(extensionElementName)) { - return extensionElement; - } - } - } - } - - return null; - } - - /** - * 获取当前任务节点扩展属性信息 - * - * @param repositoryService - * @param task 当前任务 - * @return 自定义属性列表 - */ - public static List getPropertyElement(RepositoryService repositoryService, org.flowable.task.api.Task task) { - FlowElement flowElement = getCurrentElement(repositoryService, task); - ExtensionElement extensionElement = FlowableUtils.getExtensionElementFromFlowElementByName(flowElement, "properties"); - if (extensionElement == null) { - return Collections.emptyList(); - } - return getPropertyExtensionElementByName(extensionElement, "property"); - } - - /** - * 获取当前任务节点 - * - * @param repositoryService - * @param task - * @return - */ - public static FlowElement getCurrentElement(RepositoryService repositoryService, org.flowable.task.api.Task task) { - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); - return bpmnModel.getFlowElement(task.getTaskDefinitionKey()); - } - - /** - * 根据属性名获取扩展元素中的扩展属性列表 - * - * @param extensionElement 扩展元素 - * @param attributesName 属性名 - * @return 扩展属性列表 - */ - public static List getPropertyExtensionElementByName(ExtensionElement extensionElement, String attributesName) { - try { - // 获取名称为attributesName的子元素 - return Optional.ofNullable(extensionElement.getChildElements().get(attributesName)) - .orElse(Collections.emptyList()) // 如果子元素不存在则返回空集合,避免null引用 - .stream() - .map(element -> { - // 获取子元素的属性 - Map> attributes = element.getAttributes(); - Object propertyDto = new Object(); - // 获取FlowPropertyDto的所有属性 - Arrays.stream(propertyDto.getClass().getDeclaredFields()) - .forEach(field -> { - field.setAccessible(true); - // 获取属性名称和值 - attributes.getOrDefault(field.getName(), Collections.emptyList()) - .stream() - .findFirst() - .ifPresent(attribute -> { - try { - // 反射设置属性值 - field.set(propertyDto, attribute.getValue()); - } catch (IllegalAccessException e) { - e.printStackTrace(); - // 如果反射设置失败则忽略该属性 - } - }); - }); - return propertyDto; - }).collect(Collectors.toList()); - } catch (Exception e) { - e.printStackTrace(); - return Collections.emptyList(); // 如果发生异常则返回空列表 - } - } - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowExecutionListener.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowExecutionListener.java deleted file mode 100644 index bba4fd21..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowExecutionListener.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.ruoyi.flowable.listener; - -import lombok.extern.slf4j.Slf4j; -import org.flowable.common.engine.api.delegate.Expression; -import org.flowable.engine.delegate.DelegateExecution; -import org.flowable.engine.delegate.ExecutionListener; -import org.springframework.stereotype.Component; - -/** - * 执行监听器 - * - * 执行监听器允许在执行过程中执行Java代码。 - * 执行监听器可以捕获事件的类型: - * 流程实例启动,结束 - * 输出流捕获 - * 获取启动,结束 - * 路由开始,结束 - * 中间事件开始,结束 - * 触发开始事件,触发结束事件 - * - * @author Tony - * @date 2022/12/16 - */ -@Slf4j -@Component -public class FlowExecutionListener implements ExecutionListener { - /** - * 流程设计器添加的参数 - */ - private Expression param; - - @Override - public void notify(DelegateExecution execution) { - log.info("执行监听器:{}", execution); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowTaskListener.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowTaskListener.java deleted file mode 100644 index ad3a28c3..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/listener/FlowTaskListener.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ruoyi.flowable.listener; - -import lombok.extern.slf4j.Slf4j; -import org.flowable.engine.delegate.TaskListener; -import org.flowable.task.service.delegate.DelegateTask; -import org.springframework.stereotype.Component; - -/** - * 任务监听器 - * - * create(创建):在任务被创建且所有的任务属性设置完成后才触发 - * assignment(指派):在任务被分配给某个办理人之后触发 - * complete(完成):在配置了监听器的上一个任务完成时触发 - * delete(删除):在任务即将被删除前触发。请注意任务由completeTask正常完成时也会触发 - * - * @author Tony - * @date 2021/4/20 - */ -@Slf4j -@Component -public class FlowTaskListener implements TaskListener{ - - @Override - public void notify(DelegateTask delegateTask) { - - log.info("任务监听器:{}", delegateTask); - // TODO 获取事件类型 delegateTask.getEventName(),可以通过监听器给任务执行人发送相应的通知消息 - - - } - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowDefinitionService.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowDefinitionService.java deleted file mode 100644 index f395bf27..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowDefinitionService.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.ruoyi.flowable.service; - -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.system.domain.FlowProcDefDto; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -/** - * @author Tony - * @date 2021-04-03 14:41 - */ -public interface IFlowDefinitionService { - - boolean exist(String processDefinitionKey); - - - /** - * 流程定义列表 - * - * @param pageNum 当前页码 - * @param pageSize 每页条数 - * @return 流程定义分页列表数据 - */ - Page list(String name,Integer pageNum, Integer pageSize); - - /** - * 导入流程文件 - * 当每个key的流程第一次部署时,指定版本为1。对其后所有使用相同key的流程定义, - * 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义 - * @param name - * @param category - * @param in - */ - void importFile(String name, String category, InputStream in); - - /** - * 读取xml - * @param deployId - * @return - */ - AjaxResult readXml(String deployId) throws IOException; - - /** - * 根据流程定义ID启动流程实例 - * - * @param procDefId - * @param variables - * @return - */ - - AjaxResult startProcessInstanceById(String procDefId, Map variables); - - - /** - * 激活或挂起流程定义 - * - * @param state 状态 - * @param deployId 流程部署ID - */ - void updateState(Integer state, String deployId); - - - /** - * 删除流程定义 - * - * @param deployId 流程部署ID act_ge_bytearray 表中 deployment_id值 - */ - void delete(String deployId); - - - /** - * 读取图片文件 - * @param deployId - * @return - */ - InputStream readImage(String deployId); -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowInstanceService.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowInstanceService.java deleted file mode 100644 index 8d91aaf4..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowInstanceService.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.ruoyi.flowable.service; - -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import org.flowable.engine.history.HistoricProcessInstance; -import java.util.Map; - -/** - * @author Tony - * @date 2021-04-03 14:40 - */ -public interface IFlowInstanceService { - - /** - * 结束流程实例 - * - * @param vo - */ - void stopProcessInstance(FlowTaskVo vo); - - /** - * 激活或挂起流程实例 - * - * @param state 状态 - * @param instanceId 流程实例ID - */ - void updateState(Integer state, String instanceId); - - /** - * 删除流程实例ID - * - * @param instanceId 流程实例ID - * @param deleteReason 删除原因 - */ - void delete(String instanceId, String deleteReason); - - /** - * 根据实例ID查询历史实例数据 - * - * @param processInstanceId - * @return - */ - HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId); - - /** - * 根据流程定义ID启动流程实例 - * - * @param procDefId 流程定义Id - * @param variables 流程变量 - * @return - */ - AjaxResult startProcessInstanceById(String procDefId, Map variables); -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowTaskService.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowTaskService.java deleted file mode 100644 index 8cc423da..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/IFlowTaskService.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.ruoyi.flowable.service; - -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.flowable.domain.vo.FlowQueryVo; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import org.flowable.task.api.Task; - -import java.io.InputStream; -import java.util.List; - -/** - * @author Tony - * @date 2021-04-03 14:42 - */ -public interface IFlowTaskService { - - /** - * 审批任务 - * - * @param task 请求实体参数 - */ - AjaxResult complete(FlowTaskVo task); - - /** - * 驳回任务 - * - * @param flowTaskVo - */ - void taskReject(FlowTaskVo flowTaskVo); - - - /** - * 退回任务 - * - * @param flowTaskVo 请求实体参数 - */ - void taskReturn(FlowTaskVo flowTaskVo); - - /** - * 获取所有可回退的节点 - * - * @param flowTaskVo - * @return - */ - AjaxResult findReturnTaskList(FlowTaskVo flowTaskVo); - - /** - * 删除任务 - * - * @param flowTaskVo 请求实体参数 - */ - void deleteTask(FlowTaskVo flowTaskVo); - - /** - * 认领/签收任务 - * - * @param flowTaskVo 请求实体参数 - */ - void claim(FlowTaskVo flowTaskVo); - - /** - * 取消认领/签收任务 - * - * @param flowTaskVo 请求实体参数 - */ - void unClaim(FlowTaskVo flowTaskVo); - - /** - * 委派任务 - * - * @param flowTaskVo 请求实体参数 - */ - void delegateTask(FlowTaskVo flowTaskVo); - - /** - * 任务归还 - * - * @param flowTaskVo 请求实体参数 - */ - void resolveTask(FlowTaskVo flowTaskVo); - - - /** - * 转办任务 - * - * @param flowTaskVo 请求实体参数 - */ - void assignTask(FlowTaskVo flowTaskVo); - - - /** - * 多实例加签 - * @param flowTaskVo - */ - void addMultiInstanceExecution(FlowTaskVo flowTaskVo); - - /** - * 多实例减签 - * @param flowTaskVo - */ - void deleteMultiInstanceExecution(FlowTaskVo flowTaskVo); - - /** - * 我发起的流程 - * @param queryVo 请求参数 - * @return - */ - AjaxResult myProcess(FlowQueryVo queryVo); - - /** - * 取消申请 - * 目前实现方式: 直接将当前流程变更为已完成 - * @param flowTaskVo - * @return - */ - AjaxResult stopProcess(FlowTaskVo flowTaskVo); - - /** - * 撤回流程 - * @param flowTaskVo - * @return - */ - AjaxResult revokeProcess(FlowTaskVo flowTaskVo); - - - /** - * 代办任务列表 - * - * @param queryVo 请求参数 - * @return - */ - AjaxResult todoList(FlowQueryVo queryVo); - - - /** - * 已办任务列表 - * - * @param queryVo 请求参数 - * @return - */ - AjaxResult finishedList(FlowQueryVo queryVo); - - /** - * 流程历史流转记录 - * - * @param procInsId 流程实例Id - * @return - */ - AjaxResult flowRecord(String procInsId,String deployId); - - /** - * 根据任务ID查询挂载的表单信息 - * - * @param taskId 任务Id - * @return - */ - AjaxResult getTaskForm(String taskId); - - /** - * 获取流程过程图 - * @param processId - * @return - */ - InputStream diagram(String processId); - - /** - * 获取流程执行节点 - * @param procInsId - * @return - */ - AjaxResult getFlowViewer(String procInsId,String executionId); - - /** - * 获取流程变量 - * @param taskId - * @return - */ - AjaxResult processVariables(String taskId); - - /** - * 获取下一节点 - * @param flowTaskVo 任务 - * @return - */ - AjaxResult getNextFlowNode(FlowTaskVo flowTaskVo); - - AjaxResult getNextFlowNodeByStart(FlowTaskVo flowTaskVo); - - /** - * 流程初始化表单 - * @param deployId - * @return - */ - AjaxResult flowFormData(String deployId); - - /** - * 流程节点信息 - * @param procInsId - * @return - */ - AjaxResult flowXmlAndNode(String procInsId,String deployId); - - /** - * 流程节点表单 - * @param taskId 流程任务编号 - * @return - */ - AjaxResult flowTaskForm(String taskId) throws Exception; - - - /** - * 流程节点信息 - * @param procInsId - * @param elementId - * @return - */ - AjaxResult flowTaskInfo(String procInsId, String elementId); -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysDeployFormService.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysDeployFormService.java deleted file mode 100644 index 54acf835..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysDeployFormService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.flowable.service; - -import java.util.List; -import com.ruoyi.system.domain.SysDeployForm; -import com.ruoyi.system.domain.SysForm; - -/** - * 流程实例关联表单Service接口 - * - * @author Tony - * @date 2021-04-03 - */ -public interface ISysDeployFormService -{ - /** - * 查询流程实例关联表单 - * - * @param id 流程实例关联表单ID - * @return 流程实例关联表单 - */ - public SysDeployForm selectSysDeployFormById(Long id); - - /** - * 查询流程实例关联表单列表 - * - * @param sysDeployForm 流程实例关联表单 - * @return 流程实例关联表单集合 - */ - public List selectSysDeployFormList(SysDeployForm sysDeployForm); - - /** - * 新增流程实例关联表单 - * - * @param sysDeployForm 流程实例关联表单 - * @return 结果 - */ - public int insertSysDeployForm(SysDeployForm sysDeployForm); - - /** - * 修改流程实例关联表单 - * - * @param sysDeployForm 流程实例关联表单 - * @return 结果 - */ - public int updateSysDeployForm(SysDeployForm sysDeployForm); - - /** - * 批量删除流程实例关联表单 - * - * @param ids 需要删除的流程实例关联表单ID - * @return 结果 - */ - public int deleteSysDeployFormByIds(Long[] ids); - - /** - * 删除流程实例关联表单信息 - * - * @param id 流程实例关联表单ID - * @return 结果 - */ - public int deleteSysDeployFormById(Long id); - - /** - * 查询流程挂着的表单 - * @param deployId - * @return - */ - SysForm selectSysDeployFormByDeployId(String deployId); -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysFormService.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysFormService.java deleted file mode 100644 index 3ee902b5..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/ISysFormService.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.ruoyi.flowable.service; - -import java.util.List; -import com.ruoyi.system.domain.SysForm; - -/** - * 表单 - * @author Tony - * @date 2021-04-03 - */ -public interface ISysFormService -{ - /** - * 查询流程表单 - * - * @param formId 流程表单ID - * @return 流程表单 - */ - public SysForm selectSysFormById(Long formId); - - /** - * 查询流程表单列表 - * - * @param sysForm 流程表单 - * @return 流程表单集合 - */ - public List selectSysFormList(SysForm sysForm); - - /** - * 新增流程表单 - * - * @param sysForm 流程表单 - * @return 结果 - */ - public int insertSysForm(SysForm sysForm); - - /** - * 修改流程表单 - * - * @param sysForm 流程表单 - * @return 结果 - */ - public int updateSysForm(SysForm sysForm); - - /** - * 批量删除流程表单 - * - * @param formIds 需要删除的流程表单ID - * @return 结果 - */ - public int deleteSysFormByIds(Long[] formIds); - - /** - * 删除流程表单信息 - * - * @param formId 流程表单ID - * @return 结果 - */ - public int deleteSysFormById(Long formId); -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java deleted file mode 100644 index b228590f..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.ruoyi.flowable.service.impl; - -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; -import com.ruoyi.flowable.common.constant.ProcessConstants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.flowable.common.enums.FlowComment; -import com.ruoyi.system.domain.FlowProcDefDto; -import com.ruoyi.flowable.factory.FlowServiceFactory; -import com.ruoyi.flowable.service.IFlowDefinitionService; -import com.ruoyi.flowable.service.ISysDeployFormService; -import com.ruoyi.system.domain.SysForm; -import com.ruoyi.system.mapper.FlowDeployMapper; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysPostService; -import com.ruoyi.system.service.ISysUserService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.flowable.bpmn.model.BpmnModel; -import org.flowable.engine.repository.Deployment; -import org.flowable.engine.repository.ProcessDefinition; -import org.flowable.engine.repository.ProcessDefinitionQuery; -import org.flowable.engine.runtime.ProcessInstance; -import org.flowable.image.impl.DefaultProcessDiagramGenerator; -import org.flowable.task.api.Task; -import org.springframework.beans.BeanUtils; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.*; - -/** - * 流程定义 - * - * @author Tony - * @date 2021-04-03 - */ -@Service -@Slf4j -public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFlowDefinitionService { - - @Resource - private ISysDeployFormService sysDeployFormService; - - @Resource - private ISysUserService sysUserService; - - @Resource - private ISysDeptService sysDeptService; - - @Resource - private FlowDeployMapper flowDeployMapper; - - private static final String BPMN_FILE_SUFFIX = ".bpmn"; - - @Override - public boolean exist(String processDefinitionKey) { - ProcessDefinitionQuery processDefinitionQuery - = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey); - long count = processDefinitionQuery.count(); - return count > 0 ? true : false; - } - - - /** - * 流程定义列表 - * - * @param pageNum 当前页码 - * @param pageSize 每页条数 - * @return 流程定义分页列表数据 - */ - @Override - public Page list(String name, Integer pageNum, Integer pageSize) { - Page page = new Page<>(); -// // 流程定义列表数据查询 -// final ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); -// if (StringUtils.isNotEmpty(name)) { -// processDefinitionQuery.processDefinitionNameLike(name); -// } -//// processDefinitionQuery.orderByProcessDefinitionKey().asc(); -// page.setTotal(processDefinitionQuery.count()); -// List processDefinitionList = processDefinitionQuery.listPage(pageSize * (pageNum - 1), pageSize); -// -// List dataList = new ArrayList<>(); -// for (ProcessDefinition processDefinition : processDefinitionList) { -// String deploymentId = processDefinition.getDeploymentId(); -// Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult(); -// FlowProcDefDto reProcDef = new FlowProcDefDto(); -// BeanUtils.copyProperties(processDefinition, reProcDef); -// SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(deploymentId); -// if (Objects.nonNull(sysForm)) { -// reProcDef.setFormName(sysForm.getFormName()); -// reProcDef.setFormId(sysForm.getFormId()); -// } -// // 流程定义时间 -// reProcDef.setDeploymentTime(deployment.getDeploymentTime()); -// dataList.add(reProcDef); -// } - PageHelper.startPage(pageNum, pageSize); - final List dataList = flowDeployMapper.selectDeployList(name); - // 加载挂表单 - for (FlowProcDefDto procDef : dataList) { - SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(procDef.getDeploymentId()); - if (Objects.nonNull(sysForm)) { - procDef.setFormName(sysForm.getFormName()); - procDef.setFormId(sysForm.getFormId()); - } - } - page.setTotal(new PageInfo(dataList).getTotal()); - page.setRecords(dataList); - return page; - } - - - /** - * 导入流程文件 - * - * 当每个key的流程第一次部署时,指定版本为1。对其后所有使用相同key的流程定义, - * 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义 - * @param name - * @param category - * @param in - */ - @Override - public void importFile(String name, String category, InputStream in) { - Deployment deploy = repositoryService.createDeployment().addInputStream(name + BPMN_FILE_SUFFIX, in).name(name).category(category).deploy(); - ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); - repositoryService.setProcessDefinitionCategory(definition.getId(), category); - - } - - /** - * 读取xml - * - * @param deployId - * @return - */ - @Override - public AjaxResult readXml(String deployId) throws IOException { - ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult(); - InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName()); - String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()); - return AjaxResult.success("", result); - } - - /** - * 读取xml - * - * @param deployId - * @return - */ - @Override - public InputStream readImage(String deployId) { - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult(); - //获得图片流 - DefaultProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGenerator(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); - //输出为图片 - return diagramGenerator.generateDiagram( - bpmnModel, - "png", - Collections.emptyList(), - Collections.emptyList(), - "宋体", - "宋体", - "宋体", - null, - 1.0, - false); - - } - - /** - * 根据流程定义ID启动流程实例 - * - * @param procDefId 流程模板ID - * @param variables 流程变量 - * @return - */ - @Override - public AjaxResult startProcessInstanceById(String procDefId, Map variables) { - try { - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId) - .latestVersion().singleResult(); - if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) { - return AjaxResult.error("流程已被挂起,请先激活流程"); - } - // 设置流程发起人Id到流程中 - SysUser sysUser = SecurityUtils.getLoginUser().getUser(); - identityService.setAuthenticatedUserId(sysUser.getUserId().toString()); - variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId()); - - // 流程发起时 跳过发起人节点 - ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables); - // 给第一步申请人节点设置任务执行人和意见 - Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult(); - if (Objects.nonNull(task)) { - taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), sysUser.getNickName() + "发起流程申请"); - taskService.complete(task.getId(), variables); - } - return AjaxResult.success("流程启动成功"); - } catch (Exception e) { - e.printStackTrace(); - return AjaxResult.error("流程启动错误"); - } - } - - - /** - * 激活或挂起流程定义 - * - * @param state 状态 - * @param deployId 流程部署ID - */ - @Override - public void updateState(Integer state, String deployId) { - ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult(); - // 激活 - if (state == 1) { - repositoryService.activateProcessDefinitionById(procDef.getId(), true, null); - } - // 挂起 - if (state == 2) { - repositoryService.suspendProcessDefinitionById(procDef.getId(), true, null); - } - } - - - /** - * 删除流程定义 - * - * @param deployId 流程部署ID act_ge_bytearray 表中 deployment_id值 - */ - @Override - public void delete(String deployId) { - // true 允许级联删除 ,不设置会导致数据库外键关联异常 - repositoryService.deleteDeployment(deployId, true); - } - - -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowInstanceServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowInstanceServiceImpl.java deleted file mode 100644 index 1b16384a..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowInstanceServiceImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.ruoyi.flowable.service.impl; - - -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import com.ruoyi.flowable.factory.FlowServiceFactory; -import com.ruoyi.flowable.service.IFlowInstanceService; -import lombok.extern.slf4j.Slf4j; -import org.flowable.common.engine.api.FlowableObjectNotFoundException; -import org.flowable.engine.history.HistoricProcessInstance; -import org.flowable.task.api.Task; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - *

工作流流程实例管理

- * - * @author Tony - * @date 2021-04-03 - */ -@Service -@Slf4j -public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlowInstanceService { - - /** - * 结束流程实例 - * - * @param vo - */ - @Override - public void stopProcessInstance(FlowTaskVo vo) { - String taskId = vo.getTaskId(); - - } - - /** - * 激活或挂起流程实例 - * - * @param state 状态 - * @param instanceId 流程实例ID - */ - @Override - public void updateState(Integer state, String instanceId) { - - // 激活 - if (state == 1) { - runtimeService.activateProcessInstanceById(instanceId); - } - // 挂起 - if (state == 2) { - runtimeService.suspendProcessInstanceById(instanceId); - } - } - - /** - * 删除流程实例ID - * - * @param instanceId 流程实例ID - * @param deleteReason 删除原因 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void delete(String instanceId, String deleteReason) { - - // 查询历史数据 - HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId); - if (historicProcessInstance.getEndTime() != null) { - historyService.deleteHistoricProcessInstance(historicProcessInstance.getId()); - return; - } - // 删除流程实例 - runtimeService.deleteProcessInstance(instanceId, deleteReason); - // 删除历史流程实例 - historyService.deleteHistoricProcessInstance(instanceId); - } - - /** - * 根据实例ID查询历史实例数据 - * - * @param processInstanceId - * @return - */ - @Override - public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) { - HistoricProcessInstance historicProcessInstance = - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); - if (Objects.isNull(historicProcessInstance)) { - throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId); - } - return historicProcessInstance; - } - - /** - * 根据流程定义ID启动流程实例 - * - * @param procDefId 流程定义Id - * @param variables 流程变量 - * @return - */ - @Override - public AjaxResult startProcessInstanceById(String procDefId, Map variables) { - - try { - // 设置流程发起人Id到流程中 - Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); -// identityService.setAuthenticatedUserId(userId.toString()); - variables.put("initiator",userId); - variables.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true); - runtimeService.startProcessInstanceById(procDefId, variables); - return AjaxResult.success("流程启动成功"); - } catch (Exception e) { - e.printStackTrace(); - return AjaxResult.error("流程启动错误"); - } - } -} \ No newline at end of file diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java deleted file mode 100644 index 4e5d9c0c..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java +++ /dev/null @@ -1,1262 +0,0 @@ -package com.ruoyi.flowable.service.impl; - - -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.TypeReference; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.flowable.common.constant.ProcessConstants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.flowable.common.enums.FlowComment; -import com.ruoyi.common.exception.CustomException; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.flowable.domain.dto.*; -import com.ruoyi.flowable.domain.vo.FlowQueryVo; -import com.ruoyi.flowable.domain.vo.FlowTaskVo; -import com.ruoyi.flowable.factory.FlowServiceFactory; -import com.ruoyi.flowable.flow.CustomProcessDiagramGenerator; -import com.ruoyi.flowable.flow.FindNextNodeUtil; -import com.ruoyi.flowable.flow.FlowableUtils; -import com.ruoyi.flowable.service.IFlowTaskService; -import com.ruoyi.flowable.service.ISysDeployFormService; -import com.ruoyi.flowable.service.ISysFormService; -import com.ruoyi.system.domain.SysForm; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.flowable.bpmn.model.Process; -import org.flowable.bpmn.model.*; -import org.flowable.common.engine.api.FlowableException; -import org.flowable.common.engine.api.FlowableObjectNotFoundException; -import org.flowable.engine.ProcessEngineConfiguration; -import org.flowable.engine.history.HistoricActivityInstance; -import org.flowable.engine.history.HistoricProcessInstance; -import org.flowable.engine.history.HistoricProcessInstanceQuery; -import org.flowable.engine.repository.ProcessDefinition; -import org.flowable.engine.runtime.Execution; -import org.flowable.engine.runtime.ProcessInstance; -import org.flowable.engine.task.Comment; -import org.flowable.identitylink.api.history.HistoricIdentityLink; -import org.flowable.image.ProcessDiagramGenerator; -import org.flowable.task.api.DelegationState; -import org.flowable.task.api.Task; -import org.flowable.task.api.TaskQuery; -import org.flowable.task.api.history.HistoricTaskInstance; -import org.flowable.task.api.history.HistoricTaskInstanceQuery; -import org.flowable.engine.impl.cmd.AddMultiInstanceExecutionCmd; -import org.flowable.engine.impl.cmd.DeleteMultiInstanceExecutionCmd; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * @author Tony - * @date 2021-04-03 - **/ -@Service -@Slf4j -public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTaskService { - - @Resource - private ISysUserService sysUserService; - @Resource - private ISysRoleService sysRoleService; - @Resource - private ISysDeployFormService sysInstanceFormService; - @Resource - private ISysFormService sysFormService; - - /** - * 完成任务 - * - * @param taskVo 请求实体参数 - */ - @Transactional(rollbackFor = Exception.class) - @Override - public AjaxResult complete(FlowTaskVo taskVo) { - Task task = taskService.createTaskQuery().taskId(taskVo.getTaskId()).singleResult(); - if (Objects.isNull(task)) { - return AjaxResult.error("任务不存在"); - } - if (DelegationState.PENDING.equals(task.getDelegationState())) { - taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment()); - taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables()); - } else { - taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment()); - Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); - taskService.setAssignee(taskVo.getTaskId(), userId.toString()); - taskService.complete(taskVo.getTaskId(), taskVo.getVariables()); - } - return AjaxResult.success(); - } - - /** - * 驳回任务 - * - * @param flowTaskVo - */ - @Override - public void taskReject(FlowTaskVo flowTaskVo) { - if (taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult().isSuspended()) { - throw new CustomException("任务处于挂起状态!"); - } - // 当前任务 task - Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult(); - // 获取流程定义信息 - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); - // 获取所有节点信息 - Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0); - // 获取全部节点列表,包含子节点 - Collection allElements = FlowableUtils.getAllElements(process.getFlowElements(), null); - // 获取当前任务节点元素 - FlowElement source = null; - if (allElements != null) { - for (FlowElement flowElement : allElements) { - // 类型为用户节点 - if (flowElement.getId().equals(task.getTaskDefinitionKey())) { - // 获取节点信息 - source = flowElement; - } - } - } - - // 目的获取所有跳转到的节点 targetIds - // 获取当前节点的所有父级用户任务节点 - // 深度优先算法思想:延边迭代深入 - List parentUserTaskList = FlowableUtils.iteratorFindParentUserTasks(source, null, null); - if (parentUserTaskList == null || parentUserTaskList.size() == 0) { - throw new CustomException("当前节点为初始任务节点,不能驳回"); - } - // 获取活动 ID 即节点 Key - List parentUserTaskKeyList = new ArrayList<>(); - parentUserTaskList.forEach(item -> parentUserTaskKeyList.add(item.getId())); - // 获取全部历史节点活动实例,即已经走过的节点历史,数据采用开始时间升序 - List historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceStartTime().asc().list(); - // 数据清洗,将回滚导致的脏数据清洗掉 - List lastHistoricTaskInstanceList = FlowableUtils.historicTaskInstanceClean(allElements, historicTaskInstanceList); - // 此时历史任务实例为倒序,获取最后走的节点 - List targetIds = new ArrayList<>(); - // 循环结束标识,遇到当前目标节点的次数 - int number = 0; - StringBuilder parentHistoricTaskKey = new StringBuilder(); - for (String historicTaskInstanceKey : lastHistoricTaskInstanceList) { - // 当会签时候会出现特殊的,连续都是同一个节点历史数据的情况,这种时候跳过 - if (parentHistoricTaskKey.toString().equals(historicTaskInstanceKey)) { - continue; - } - parentHistoricTaskKey = new StringBuilder(historicTaskInstanceKey); - if (historicTaskInstanceKey.equals(task.getTaskDefinitionKey())) { - number++; - } - // 在数据清洗后,历史节点就是唯一一条从起始到当前节点的历史记录,理论上每个点只会出现一次 - // 在流程中如果出现循环,那么每次循环中间的点也只会出现一次,再出现就是下次循环 - // number == 1,第一次遇到当前节点 - // number == 2,第二次遇到,代表最后一次的循环范围 - if (number == 2) { - break; - } - // 如果当前历史节点,属于父级的节点,说明最后一次经过了这个点,需要退回这个点 - if (parentUserTaskKeyList.contains(historicTaskInstanceKey)) { - targetIds.add(historicTaskInstanceKey); - } - } - - - // 目的获取所有需要被跳转的节点 currentIds - // 取其中一个父级任务,因为后续要么存在公共网关,要么就是串行公共线路 - UserTask oneUserTask = parentUserTaskList.get(0); - // 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务 - List runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); - List runTaskKeyList = new ArrayList<>(); - runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey())); - // 需驳回任务列表 - List currentIds = new ArrayList<>(); - // 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务 - List currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(oneUserTask, runTaskKeyList, null, null); - currentUserTaskList.forEach(item -> currentIds.add(item.getId())); - - - // 规定:并行网关之前节点必须需存在唯一用户任务节点,如果出现多个任务节点,则并行网关节点默认为结束节点,原因为不考虑多对多情况 - if (targetIds.size() > 1 && currentIds.size() > 1) { - throw new CustomException("任务出现多对多情况,无法撤回"); - } - - // 循环获取那些需要被撤回的节点的ID,用来设置驳回原因 - List currentTaskIds = new ArrayList<>(); - currentIds.forEach(currentId -> runTaskList.forEach(runTask -> { - if (currentId.equals(runTask.getTaskDefinitionKey())) { - currentTaskIds.add(runTask.getId()); - } - })); - // 设置驳回意见 - currentTaskIds.forEach(item -> taskService.addComment(item, task.getProcessInstanceId(), FlowComment.REJECT.getType(), flowTaskVo.getComment())); - - try { - // 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况 - if (targetIds.size() > 1) { - // 1 对 多任务跳转,currentIds 当前节点(1),targetIds 跳转到的节点(多) - runtimeService.createChangeActivityStateBuilder() - .processInstanceId(task.getProcessInstanceId()). - moveSingleActivityIdToActivityIds(currentIds.get(0), targetIds).changeState(); - } - // 如果父级任务只有一个,因此当前任务可能为网关中的任务 - if (targetIds.size() == 1) { - // 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetIds.get(0) 跳转到的节点(1) - runtimeService.createChangeActivityStateBuilder() - .processInstanceId(task.getProcessInstanceId()) - .moveActivityIdsToSingleActivityId(currentIds, targetIds.get(0)).changeState(); - } - } catch (FlowableObjectNotFoundException e) { - throw new CustomException("未找到流程实例,流程可能已发生变化"); - } catch (FlowableException e) { - throw new CustomException("无法取消或开始活动"); - } - - } - - /** - * 退回任务 - * - * @param flowTaskVo 请求实体参数 - */ - @Transactional(rollbackFor = Exception.class) - @Override - public void taskReturn(FlowTaskVo flowTaskVo) { - if (taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult().isSuspended()) { - throw new CustomException("任务处于挂起状态"); - } - // 当前任务 task - Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult(); - // 获取流程定义信息 - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); - // 获取所有节点信息 - Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0); - // 获取全部节点列表,包含子节点 - Collection allElements = FlowableUtils.getAllElements(process.getFlowElements(), null); - // 获取当前任务节点元素 - FlowElement source = null; - // 获取跳转的节点元素 - FlowElement target = null; - if (allElements != null) { - for (FlowElement flowElement : allElements) { - // 当前任务节点元素 - if (flowElement.getId().equals(task.getTaskDefinitionKey())) { - source = flowElement; - } - // 跳转的节点元素 - if (flowElement.getId().equals(flowTaskVo.getTargetKey())) { - target = flowElement; - } - } - } - - // 从当前节点向前扫描 - // 如果存在路线上不存在目标节点,说明目标节点是在网关上或非同一路线上,不可跳转 - // 否则目标节点相对于当前节点,属于串行 - Boolean isSequential = FlowableUtils.iteratorCheckSequentialReferTarget(source, flowTaskVo.getTargetKey(), null, null); - if (!isSequential) { - throw new CustomException("当前节点相对于目标节点,不属于串行关系,无法回退"); - } - - - // 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务 - List runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); - List runTaskKeyList = new ArrayList<>(); - runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey())); - // 需退回任务列表 - List currentIds = new ArrayList<>(); - // 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务 - List currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(target, runTaskKeyList, null, null); - currentUserTaskList.forEach(item -> currentIds.add(item.getId())); - - // 循环获取那些需要被撤回的节点的ID,用来设置驳回原因 - List currentTaskIds = new ArrayList<>(); - currentIds.forEach(currentId -> runTaskList.forEach(runTask -> { - if (currentId.equals(runTask.getTaskDefinitionKey())) { - currentTaskIds.add(runTask.getId()); - } - })); - // 设置回退意见 - currentTaskIds.forEach(currentTaskId -> taskService.addComment(currentTaskId, task.getProcessInstanceId(), FlowComment.REBACK.getType(), flowTaskVo.getComment())); - - try { - // 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetKey 跳转到的节点(1) - runtimeService.createChangeActivityStateBuilder() - .processInstanceId(task.getProcessInstanceId()) - .moveActivityIdsToSingleActivityId(currentIds, flowTaskVo.getTargetKey()).changeState(); - } catch (FlowableObjectNotFoundException e) { - throw new CustomException("未找到流程实例,流程可能已发生变化"); - } catch (FlowableException e) { - throw new CustomException("无法取消或开始活动"); - } - } - - - /** - * 获取所有可回退的节点 - * - * @param flowTaskVo - * @return - */ - @Override - public AjaxResult findReturnTaskList(FlowTaskVo flowTaskVo) { - // 当前任务 task - Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult(); - // 获取流程定义信息 - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); - // 获取所有节点信息,暂不考虑子流程情况 - Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0); - Collection flowElements = process.getFlowElements(); - // 获取当前任务节点元素 - UserTask source = null; - if (flowElements != null) { - for (FlowElement flowElement : flowElements) { - // 类型为用户节点 - if (flowElement.getId().equals(task.getTaskDefinitionKey())) { - source = (UserTask) flowElement; - } - } - } - // 获取节点的所有路线 - List> roads = FlowableUtils.findRoad(source, null, null, null); - // 可回退的节点列表 - List userTaskList = new ArrayList<>(); - for (List road : roads) { - if (userTaskList.size() == 0) { - // 还没有可回退节点直接添加 - userTaskList = road; - } else { - // 如果已有回退节点,则比对取交集部分 - userTaskList.retainAll(road); - } - } - return AjaxResult.success(userTaskList); - } - - /** - * 删除任务 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - public void deleteTask(FlowTaskVo flowTaskVo) { - // todo 待确认删除任务是物理删除任务 还是逻辑删除,让这个任务直接通过? - taskService.deleteTask(flowTaskVo.getTaskId(), flowTaskVo.getComment()); - } - - /** - * 认领/签收任务 - * 认领以后,这个用户就会成为任务的执行人,任务会从其他成员的任务列表中消失 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void claim(FlowTaskVo flowTaskVo) { - taskService.claim(flowTaskVo.getTaskId(), flowTaskVo.getUserId()); - } - - /** - * 取消认领/签收任务 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void unClaim(FlowTaskVo flowTaskVo) { - taskService.unclaim(flowTaskVo.getTaskId()); - } - - /** - * 委派任务 - * 任务委派只是委派人将当前的任务交给被委派人进行审批,处理任务后又重新回到委派人身上。 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void delegateTask(FlowTaskVo flowTaskVo) { - taskService.delegateTask(flowTaskVo.getTaskId(), flowTaskVo.getAssignee()); - } - - /** - * 任务归还 - * 被委派人完成任务之后,将任务归还委派人 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void resolveTask(FlowTaskVo flowTaskVo) { - taskService.resolveTask(flowTaskVo.getTaskId()); - } - - - /** - * 转办任务 - * 直接将办理人换成别人,这时任务的拥有者不再是转办人 - * - * @param flowTaskVo 请求实体参数 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void assignTask(FlowTaskVo flowTaskVo) { - // 直接转派就可以覆盖掉之前的 - taskService.setAssignee(flowTaskVo.getTaskId(), flowTaskVo.getAssignee()); -// // 删除指派人重新指派 -// taskService.deleteCandidateUser(flowTaskVo.getTaskId(),flowTaskVo.getAssignee()); -// taskService.addCandidateUser(flowTaskVo.getTaskId(),flowTaskVo.getAssignee()); -// // 如果要查询转给他人处理的任务,可以同时将OWNER进行设置: -// taskService.setOwner(flowTaskVo.getTaskId(), flowTaskVo.getAssignee()); - - } - - /** - * 多实例加签 - * act_ru_task、act_ru_identitylink各生成一条记录 - * - * @param flowTaskVo - */ - @Override - public void addMultiInstanceExecution(FlowTaskVo flowTaskVo) { - managementService.executeCommand(new AddMultiInstanceExecutionCmd(flowTaskVo.getDefId(), flowTaskVo.getInstanceId(), flowTaskVo.getVariables())); - } - - /** - * 多实例减签 - * act_ru_task减1、act_ru_identitylink不变 - * - * @param flowTaskVo - */ - @Override - public void deleteMultiInstanceExecution(FlowTaskVo flowTaskVo) { - managementService.executeCommand(new DeleteMultiInstanceExecutionCmd(flowTaskVo.getCurrentChildExecutionId(), flowTaskVo.getFlag())); - } - - /** - * 我发起的流程 - * - * @param queryVo 请求参数 - * @return - */ - @Override - public AjaxResult myProcess(FlowQueryVo queryVo) { - Page page = new Page<>(); - Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); - HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() - .startedBy(userId.toString()) - .orderByProcessInstanceStartTime() - .desc(); - List historicProcessInstances = historicProcessInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize()); - page.setTotal(historicProcessInstanceQuery.count()); - List flowList = new ArrayList<>(); - for (HistoricProcessInstance hisIns : historicProcessInstances) { - FlowTaskDto flowTask = new FlowTaskDto(); - flowTask.setCreateTime(hisIns.getStartTime()); - flowTask.setFinishTime(hisIns.getEndTime()); - flowTask.setProcInsId(hisIns.getId()); - - // 计算耗时 - if (Objects.nonNull(hisIns.getEndTime())) { - long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime(); - flowTask.setDuration(getDate(time)); - } else { - long time = System.currentTimeMillis() - hisIns.getStartTime().getTime(); - flowTask.setDuration(getDate(time)); - } - // 流程定义信息 - ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() - .processDefinitionId(hisIns.getProcessDefinitionId()) - .singleResult(); - flowTask.setDeployId(pd.getDeploymentId()); - flowTask.setProcDefName(pd.getName()); - flowTask.setProcDefVersion(pd.getVersion()); - flowTask.setCategory(pd.getCategory()); - flowTask.setProcDefVersion(pd.getVersion()); - // 当前所处流程 - List taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list(); - if (CollectionUtils.isNotEmpty(taskList)) { - flowTask.setTaskId(taskList.get(0).getId()); - flowTask.setTaskName(taskList.get(0).getName()); - if (StringUtils.isNotBlank(taskList.get(0).getAssignee())) { - // 当前任务节点办理人信息 - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(taskList.get(0).getAssignee())); - if (Objects.nonNull(sysUser)) { - flowTask.setAssigneeId(sysUser.getUserId()); - flowTask.setAssigneeName(sysUser.getNickName()); - flowTask.setAssigneeDeptName(Objects.nonNull(sysUser.getDept()) ? sysUser.getDept().getDeptName() : ""); - } - } - } else { - List historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list(); - flowTask.setTaskId(historicTaskInstance.get(0).getId()); - flowTask.setTaskName(historicTaskInstance.get(0).getName()); - if (StringUtils.isNotBlank(historicTaskInstance.get(0).getAssignee())) { - // 当前任务节点办理人信息 - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(historicTaskInstance.get(0).getAssignee())); - if (Objects.nonNull(sysUser)) { - flowTask.setAssigneeId(sysUser.getUserId()); - flowTask.setAssigneeName(sysUser.getNickName()); - flowTask.setAssigneeDeptName(Objects.nonNull(sysUser.getDept()) ? sysUser.getDept().getDeptName() : ""); - } - } - } - flowList.add(flowTask); - } - page.setRecords(flowList); - return AjaxResult.success(page); - } - - /** - * 取消申请 - * 目前实现方式: 直接将当前流程变更为已完成 - * - * @param flowTaskVo - * @return - */ - @Override - public AjaxResult stopProcess(FlowTaskVo flowTaskVo) { - List task = taskService.createTaskQuery().processInstanceId(flowTaskVo.getInstanceId()).list(); - if (CollectionUtils.isEmpty(task)) { - throw new CustomException("流程未启动或已执行完成,取消申请失败"); - } - // 获取当前流程实例 - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() - .processInstanceId(flowTaskVo.getInstanceId()) - .singleResult(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); - if (Objects.nonNull(bpmnModel)) { - Process process = bpmnModel.getMainProcess(); - List endNodes = process.findFlowElementsOfType(EndEvent.class, false); - if (CollectionUtils.isNotEmpty(endNodes)) { - // TODO 取消流程为什么要设置流程发起人? -// SysUser loginUser = SecurityUtils.getLoginUser().getUser(); -// Authentication.setAuthenticatedUserId(loginUser.getUserId().toString()); - -// taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(), -// StringUtils.isBlank(flowTaskVo.getComment()) ? "取消申请" : flowTaskVo.getComment()); - // 获取当前流程最后一个节点 - String endId = endNodes.get(0).getId(); - List executions = runtimeService.createExecutionQuery() - .parentId(processInstance.getProcessInstanceId()).list(); - List executionIds = new ArrayList<>(); - executions.forEach(execution -> executionIds.add(execution.getId())); - // 变更流程为已结束状态 - runtimeService.createChangeActivityStateBuilder() - .moveExecutionsToSingleActivityId(executionIds, endId).changeState(); - } - } - - return AjaxResult.success(); - } - - /** - * 撤回流程 目前存在错误 - * - * @param flowTaskVo - * @return - */ - @Override - public AjaxResult revokeProcess(FlowTaskVo flowTaskVo) { - Task task = taskService.createTaskQuery() - .processInstanceId(flowTaskVo.getInstanceId()) - .singleResult(); - if (task == null) { - throw new CustomException("流程未启动或已执行完成,无法撤回"); - } - - SysUser loginUser = SecurityUtils.getLoginUser().getUser(); - List htiList = historyService.createHistoricTaskInstanceQuery() - .processInstanceId(task.getProcessInstanceId()) - .orderByTaskCreateTime() - .asc() - .list(); - String myTaskId = null; - for (HistoricTaskInstance hti : htiList) { - if (loginUser.getUserId().toString().equals(hti.getAssignee())) { - myTaskId = hti.getId(); - break; - } - } - if (null == myTaskId) { - throw new CustomException("该任务非当前用户提交,无法撤回"); - } - List historicTaskInstanceList = historyService - .createHistoricTaskInstanceQuery() - .processInstanceId(task.getProcessInstanceId()) - .orderByHistoricTaskInstanceStartTime() - .asc() - .list(); - Iterator it = historicTaskInstanceList.iterator(); - //循环节点,获取当前节点的上一节点的key - String tarKey = ""; - while (it.hasNext()) { - HistoricTaskInstance his = it.next(); - if (!task.getTaskDefinitionKey().equals(his.getTaskDefinitionKey())) { - tarKey = his.getTaskDefinitionKey(); - } - } - // 跳转节点 - runtimeService.createChangeActivityStateBuilder() - .processInstanceId(flowTaskVo.getInstanceId()) - .moveActivityIdTo(task.getTaskDefinitionKey(), tarKey) - .changeState(); - - return AjaxResult.success(); - } - - /** - * 代办任务列表 - * - * @param queryVo 请求参数 - * @return - */ - @Override - public AjaxResult todoList(FlowQueryVo queryVo) { - Page page = new Page<>(); - // 只查看自己的数据 - SysUser sysUser = SecurityUtils.getLoginUser().getUser(); - TaskQuery taskQuery = taskService.createTaskQuery() - .active() - .includeProcessVariables() - .taskCandidateGroupIn(sysUser.getRoles().stream().map(role -> role.getRoleId().toString()).collect(Collectors.toList())) - .taskCandidateOrAssigned(sysUser.getUserId().toString()) - .orderByTaskCreateTime().desc(); - -// TODO 传入名称查询不到数据? - if (StringUtils.isNotBlank(queryVo.getName())) { - taskQuery.processDefinitionNameLike(queryVo.getName()); - } - page.setTotal(taskQuery.count()); - List taskList = taskQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize()); - List flowList = new ArrayList<>(); - for (Task task : taskList) { - FlowTaskDto flowTask = new FlowTaskDto(); - // 当前流程信息 - flowTask.setTaskId(task.getId()); - flowTask.setTaskDefKey(task.getTaskDefinitionKey()); - flowTask.setCreateTime(task.getCreateTime()); - flowTask.setProcDefId(task.getProcessDefinitionId()); - flowTask.setExecutionId(task.getExecutionId()); - flowTask.setTaskName(task.getName()); - // 流程定义信息 - ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() - .processDefinitionId(task.getProcessDefinitionId()) - .singleResult(); - flowTask.setDeployId(pd.getDeploymentId()); - flowTask.setProcDefName(pd.getName()); - flowTask.setProcDefVersion(pd.getVersion()); - flowTask.setProcInsId(task.getProcessInstanceId()); - - // 流程发起人信息 - HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() - .processInstanceId(task.getProcessInstanceId()) - .singleResult(); - SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId())); - flowTask.setStartUserId(startUser.getUserId().toString()); - flowTask.setStartUserName(startUser.getNickName()); - flowTask.setStartDeptName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : ""); - flowList.add(flowTask); - } - - page.setRecords(flowList); - return AjaxResult.success(page); - } - - - /** - * 已办任务列表 - * - * @param queryVo 请求参数 - * @return - */ - @Override - public AjaxResult finishedList(FlowQueryVo queryVo) { - Page page = new Page<>(); - Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); - HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery() - .includeProcessVariables() - .finished() - .taskAssignee(userId.toString()) - .orderByHistoricTaskInstanceEndTime() - .desc(); - List historicTaskInstanceList = taskInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize()); - List hisTaskList = new ArrayList<>(); - for (HistoricTaskInstance histTask : historicTaskInstanceList) { - FlowTaskDto flowTask = new FlowTaskDto(); - // 当前流程信息 - flowTask.setTaskId(histTask.getId()); - // 审批人员信息 - flowTask.setCreateTime(histTask.getCreateTime()); - flowTask.setFinishTime(histTask.getEndTime()); - flowTask.setDuration(getDate(histTask.getDurationInMillis())); - flowTask.setProcDefId(histTask.getProcessDefinitionId()); - flowTask.setTaskDefKey(histTask.getTaskDefinitionKey()); - flowTask.setTaskName(histTask.getName()); - - // 流程定义信息 - ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() - .processDefinitionId(histTask.getProcessDefinitionId()) - .singleResult(); - flowTask.setDeployId(pd.getDeploymentId()); - flowTask.setProcDefName(pd.getName()); - flowTask.setProcDefVersion(pd.getVersion()); - flowTask.setProcInsId(histTask.getProcessInstanceId()); - flowTask.setHisProcInsId(histTask.getProcessInstanceId()); - - // 流程发起人信息 - HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() - .processInstanceId(histTask.getProcessInstanceId()) - .singleResult(); - SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId())); - flowTask.setStartUserId(startUser.getNickName()); - flowTask.setStartUserName(startUser.getNickName()); - flowTask.setStartDeptName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : ""); - hisTaskList.add(flowTask); - } - page.setTotal(taskInstanceQuery.count()); - page.setRecords(hisTaskList); - return AjaxResult.success(page); - } - - private static Predicate distinctByKey(Function keyExtractor) { - Set seen = ConcurrentHashMap.newKeySet(); - return t -> seen.add(keyExtractor.apply(t)); - } - - /** - * 流程历史流转记录 - * - * @param procInsId 流程实例Id - * @return - */ - @Override - public AjaxResult flowRecord(String procInsId, String deployId) { - Map map = new HashMap(); - if (StringUtils.isNotBlank(procInsId)) { - List list = historyService - .createHistoricActivityInstanceQuery() - .processInstanceId(procInsId) - .orderByHistoricActivityInstanceStartTime() - .desc().list(); - List hisFlowList = new ArrayList<>(); - for (HistoricActivityInstance histIns : list) { - // 展示开始节点 -// if ("startEvent".equals(histIns.getActivityType())) { -// FlowTaskDto flowTask = new FlowTaskDto(); -// // 流程发起人信息 -// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() -// .processInstanceId(histIns.getProcessInstanceId()) -// .singleResult(); -// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId())); -// flowTask.setTaskName(startUser.getNickName() + "(" + startUser.getDept().getDeptName() + ")发起申请"); -// flowTask.setFinishTime(histIns.getEndTime()); -// hisFlowList.add(flowTask); -// } else if ("endEvent".equals(histIns.getActivityType())) { -// FlowTaskDto flowTask = new FlowTaskDto(); -// flowTask.setTaskName(StringUtils.isNotBlank(histIns.getActivityName()) ? histIns.getActivityName() : "结束"); -// flowTask.setFinishTime(histIns.getEndTime()); -// hisFlowList.add(flowTask); -// } else - if (StringUtils.isNotBlank(histIns.getTaskId())) { - FlowTaskDto flowTask = new FlowTaskDto(); - flowTask.setTaskId(histIns.getTaskId()); - flowTask.setTaskName(histIns.getActivityName()); - flowTask.setCreateTime(histIns.getStartTime()); - flowTask.setFinishTime(histIns.getEndTime()); - if (StringUtils.isNotBlank(histIns.getAssignee())) { - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(histIns.getAssignee())); - flowTask.setAssigneeId(sysUser.getUserId()); - flowTask.setAssigneeName(sysUser.getNickName()); - flowTask.setDeptName(Objects.nonNull(sysUser.getDept()) ? sysUser.getDept().getDeptName() : ""); - } - // 展示审批人员 - List linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId()); - StringBuilder stringBuilder = new StringBuilder(); - for (HistoricIdentityLink identityLink : linksForTask) { - // 获选人,候选组/角色(多个) - if ("candidate".equals(identityLink.getType())) { - if (StringUtils.isNotBlank(identityLink.getUserId())) { - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); - stringBuilder.append(sysUser.getNickName()).append(","); - } - if (StringUtils.isNotBlank(identityLink.getGroupId())) { - SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); - stringBuilder.append(sysRole.getRoleName()).append(","); - } - } - } - if (StringUtils.isNotBlank(stringBuilder)) { - flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1)); - } - - flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null : getDate(histIns.getDurationInMillis())); - // 获取意见评论内容 - List commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId()); - commentList.forEach(comment -> { - if (histIns.getTaskId().equals(comment.getTaskId())) { - flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build()); - } - }); - hisFlowList.add(flowTask); - } - } - map.put("flowList", hisFlowList); - } - // 第一次申请获取初始化表单 - if (StringUtils.isNotBlank(deployId)) { - SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId); - if (Objects.isNull(sysForm)) { - return AjaxResult.error("请先配置流程表单"); - } - map.put("formData", JSONObject.parseObject(sysForm.getFormContent())); - } - return AjaxResult.success(map); - } - - /** - * 根据任务ID查询挂载的表单信息 - * - * @param taskId 任务Id - * @return - */ - @Override - public AjaxResult getTaskForm(String taskId) { - Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); - SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(task.getFormKey())); - return AjaxResult.success(sysForm.getFormContent()); - } - - /** - * 获取流程过程图 - * - * @param processId - * @return - */ - @Override - public InputStream diagram(String processId) { - String processDefinitionId; - // 获取当前的流程实例 - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult(); - // 如果流程已经结束,则得到结束节点 - if (Objects.isNull(processInstance)) { - HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult(); - - processDefinitionId = pi.getProcessDefinitionId(); - } else {// 如果流程没有结束,则取当前活动节点 - // 根据流程实例ID获得当前处于活动状态的ActivityId合集 - ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult(); - processDefinitionId = pi.getProcessDefinitionId(); - } - - // 获得活动的节点 - List highLightedFlowList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list(); - - List highLightedFlows = new ArrayList<>(); - List highLightedNodes = new ArrayList<>(); - //高亮线 - for (HistoricActivityInstance tempActivity : highLightedFlowList) { - if ("sequenceFlow".equals(tempActivity.getActivityType())) { - //高亮线 - highLightedFlows.add(tempActivity.getActivityId()); - } else { - //高亮节点 - highLightedNodes.add(tempActivity.getActivityId()); - } - } - - //获取流程图 - BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); - ProcessEngineConfiguration configuration = processEngine.getProcessEngineConfiguration(); - //获取自定义图片生成器 - ProcessDiagramGenerator diagramGenerator = new CustomProcessDiagramGenerator(); - InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(), - configuration.getLabelFontName(), configuration.getAnnotationFontName(), configuration.getClassLoader(), 1.0, true); - return in; - - } - - /** - * 获取流程执行节点 - * - * @param procInsId 流程实例id - * @return - */ - @Override - public AjaxResult getFlowViewer(String procInsId, String executionId) { - List flowViewerList = new ArrayList<>(); - FlowViewerDto flowViewerDto; - // 获取任务开始节点(临时处理方式) - List startNodeList = historyService.createHistoricActivityInstanceQuery() - .processInstanceId(procInsId) - .orderByHistoricActivityInstanceStartTime() - .asc().listPage(0, 3); - for (HistoricActivityInstance startInstance : startNodeList) { - if (!"sequenceFlow".equals(startInstance.getActivityType())) { - flowViewerDto = new FlowViewerDto(); - if (!"sequenceFlow".equals(startInstance.getActivityType())) { - flowViewerDto.setKey(startInstance.getActivityId()); - // 根据流程节点处理时间校验改节点是否已完成 - flowViewerDto.setCompleted(!Objects.isNull(startInstance.getEndTime())); - flowViewerList.add(flowViewerDto); - } - } - } - // 历史节点 - List hisActIns = historyService.createHistoricActivityInstanceQuery() - .executionId(executionId) - .orderByHistoricActivityInstanceStartTime() - .asc().list(); - for (HistoricActivityInstance activityInstance : hisActIns) { - if (!"sequenceFlow".equals(activityInstance.getActivityType())) { - flowViewerDto = new FlowViewerDto(); - flowViewerDto.setKey(activityInstance.getActivityId()); - // 根据流程节点处理时间校验改节点是否已完成 - flowViewerDto.setCompleted(!Objects.isNull(activityInstance.getEndTime())); - flowViewerList.add(flowViewerDto); - } - } - return AjaxResult.success(flowViewerList); - } - - /** - * 获取流程变量 - * - * @param taskId - * @return - */ - @Override - public AjaxResult processVariables(String taskId) { - // 流程变量 - HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult(); - if (Objects.nonNull(historicTaskInstance)) { - return AjaxResult.success(historicTaskInstance.getProcessVariables()); - } else { - Map variables = taskService.getVariables(taskId); - return AjaxResult.success(variables); - } - } - - /** - * 审批任务获取下一节点 - * - * @param flowTaskVo 任务 - * @return - */ - @Override - public AjaxResult getNextFlowNode(FlowTaskVo flowTaskVo) { - // Step 1. 获取当前节点并找到下一步节点 - Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult(); - if (Objects.isNull(task)) { - return AjaxResult.error("任务不存在或已被审批!"); - } - // Step 2. 获取当前流程所有流程变量(网关节点时需要校验表达式) - Map variables = taskService.getVariables(task.getId()); - List nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, variables); - if (CollectionUtils.isEmpty(nextUserTask)) { - return AjaxResult.success("流程已完结!", null); - } - return getFlowAttribute(nextUserTask); - } - - /** - * 发起流程获取下一节点 - * - * @param flowTaskVo 任务 - * @return - */ - @Override - public AjaxResult getNextFlowNodeByStart(FlowTaskVo flowTaskVo) { - // Step 1. 查找流程定义信息 - ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(flowTaskVo.getDeploymentId()).singleResult(); - if (Objects.isNull(processDefinition)) { - return AjaxResult.error("流程信息不存在!"); - } - // Step 2. 获取下一任务节点(网关节点时需要校验表达式) - List nextUserTask = FindNextNodeUtil.getNextUserTasksByStart(repositoryService, processDefinition, flowTaskVo.getVariables()); - if (CollectionUtils.isEmpty(nextUserTask)) { - return AjaxResult.error("暂未查找到下一任务,请检查流程设计是否正确!"); - } - return getFlowAttribute(nextUserTask); - } - - - /** - * 获取任务节点属性,包含自定义属性等 - * - * @param nextUserTask - */ - private AjaxResult getFlowAttribute(List nextUserTask) { - FlowNextDto flowNextDto = new FlowNextDto(); - for (UserTask userTask : nextUserTask) { - MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics(); - // 会签节点 - if (Objects.nonNull(multiInstance)) { - flowNextDto.setVars(multiInstance.getInputDataItem()); - flowNextDto.setType(ProcessConstants.PROCESS_MULTI_INSTANCE); - flowNextDto.setDataType(ProcessConstants.DYNAMIC); - } else { - // 读取自定义节点属性 判断是否是否需要动态指定任务接收人员、组 - String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); - String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE); - flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL); - flowNextDto.setType(userType); - flowNextDto.setDataType(dataType); - } - } - return AjaxResult.success(flowNextDto); - } - - /** - * 流程初始化表单 - * - * @param deployId - * @return - */ - @Override - public AjaxResult flowFormData(String deployId) { - // 第一次申请获取初始化表单 - if (StringUtils.isNotBlank(deployId)) { - SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId); - if (Objects.isNull(sysForm)) { - return AjaxResult.error("请先配置流程表单!"); - } - return AjaxResult.success(JSONObject.parseObject(sysForm.getFormContent())); - } else { - return AjaxResult.error("参数错误!"); - } - } - - /** - * 流程节点信息 - * - * @param procInsId - * @return - */ - @Override - public AjaxResult flowXmlAndNode(String procInsId, String deployId) { - try { - List flowViewerList = new ArrayList<>(); - // 获取已经完成的节点 - List listFinished = historyService.createHistoricActivityInstanceQuery() - .processInstanceId(procInsId) - .finished() - .list(); - - // 保存已经完成的流程节点编号 - listFinished.forEach(s -> { - FlowViewerDto flowViewerDto = new FlowViewerDto(); - flowViewerDto.setKey(s.getActivityId()); - flowViewerDto.setCompleted(true); - // 退回节点不进行展示 - if (StringUtils.isBlank(s.getDeleteReason())) { - flowViewerList.add(flowViewerDto); - } - }); - - // 获取代办节点 - List listUnFinished = historyService.createHistoricActivityInstanceQuery() - .processInstanceId(procInsId) - .unfinished() - .list(); - - // 保存需要代办的节点编号 - listUnFinished.forEach(s -> { - // 删除已退回节点 - flowViewerList.removeIf(task -> task.getKey().equals(s.getActivityId())); - FlowViewerDto flowViewerDto = new FlowViewerDto(); - flowViewerDto.setKey(s.getActivityId()); - flowViewerDto.setCompleted(false); - flowViewerList.add(flowViewerDto); - }); - Map result = new HashMap(); - // xmlData 数据 - ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult(); - InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName()); - String xmlData = IOUtils.toString(inputStream, StandardCharsets.UTF_8); - result.put("nodeData", flowViewerList); - result.put("xmlData", xmlData); - return AjaxResult.success(result); - } catch (Exception e) { - return AjaxResult.error("高亮历史任务失败"); - } - } - - /** - * 流程节点表单 - * - * @param taskId 流程任务编号 - * @return - */ - @Override - public AjaxResult flowTaskForm(String taskId) throws Exception { - Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); - // 流程变量 - Map parameters = new HashMap<>(); - HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult(); - if (Objects.nonNull(historicTaskInstance)) { - parameters = historicTaskInstance.getProcessVariables(); - } else { - parameters = taskService.getVariables(taskId); - } - JSONObject oldVariables = JSONObject.parseObject(JSON.toJSONString(parameters.get("formJson"))); - List oldFields = JSON.parseObject(JSON.toJSONString(oldVariables.get("widgetList")), new TypeReference>() { - }); - // 设置已填写的表单为禁用状态 - for (JSONObject oldField : oldFields) { - JSONObject options = oldField.getJSONObject("options"); - options.put("disabled", true); - } - // TODO 暂时只处理用户任务上的表单 - if (StringUtils.isNotBlank(task.getFormKey())) { - SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(task.getFormKey())); - JSONObject data = JSONObject.parseObject(sysForm.getFormContent()); - List newFields = JSON.parseObject(JSON.toJSONString(data.get("widgetList")), new TypeReference>() { - }); - // 表单回显时 加入子表单信息到流程变量中 - for (JSONObject newField : newFields) { - String key = newField.getString("id"); - // 处理图片上传组件回显问题 - if ("picture-upload".equals(newField.getString("type"))) { - parameters.put(key, new ArrayList<>()); - } else { - parameters.put(key, null); - } - } - oldFields.addAll(newFields); - } - oldVariables.put("widgetList", oldFields); - parameters.put("formJson", oldVariables); - return AjaxResult.success(parameters); - } - - /** - * 流程节点信息 - * - * @param procInsId - * @param elementId - * @return - */ - @Override - public AjaxResult flowTaskInfo(String procInsId, String elementId) { - List list = historyService.createHistoricActivityInstanceQuery() - .processInstanceId(procInsId) - .activityId(elementId) - .list(); - // 退回任务后有多条数据 只取待办任务进行展示 - list.removeIf(task -> StringUtils.isNotBlank(task.getDeleteReason())); - if (CollectionUtils.isEmpty(list)) { - return AjaxResult.success(); - } - if (list.size() > 1) { - list.removeIf(task -> Objects.nonNull(task.getEndTime())); - } - HistoricActivityInstance histIns = list.get(0); - FlowTaskDto flowTask = new FlowTaskDto(); - flowTask.setTaskId(histIns.getTaskId()); - flowTask.setTaskName(histIns.getActivityName()); - flowTask.setCreateTime(histIns.getStartTime()); - flowTask.setFinishTime(histIns.getEndTime()); - if (StringUtils.isNotBlank(histIns.getAssignee())) { - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(histIns.getAssignee())); - flowTask.setAssigneeId(sysUser.getUserId()); - flowTask.setAssigneeName(sysUser.getNickName()); - flowTask.setDeptName(Objects.nonNull(sysUser.getDept()) ? sysUser.getDept().getDeptName() : ""); - - } - // 流程变量信息 -// HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() -// .includeProcessVariables().finished().taskId(histIns.getTaskId()).singleResult(); -// flowTask.setVariables(historicTaskInstance.getProcessVariables()); - - // 展示审批人员 - List linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId()); - StringBuilder stringBuilder = new StringBuilder(); - for (HistoricIdentityLink identityLink : linksForTask) { - // 获选人,候选组/角色(多个) - if ("candidate".equals(identityLink.getType())) { - if (StringUtils.isNotBlank(identityLink.getUserId())) { - SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); - stringBuilder.append(sysUser.getNickName()).append(","); - } - if (StringUtils.isNotBlank(identityLink.getGroupId())) { - SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); - stringBuilder.append(sysRole.getRoleName()).append(","); - } - } - } - if (StringUtils.isNotBlank(stringBuilder)) { - flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1)); - } - - flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null : getDate(histIns.getDurationInMillis())); - // 获取意见评论内容 - List commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId()); - commentList.forEach(comment -> { - if (histIns.getTaskId().equals(comment.getTaskId())) { - flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build()); - } - }); - return AjaxResult.success(flowTask); - } - - /** - * 将Object类型的数据转化成Map - * - * @param obj - * @return - * @throws Exception - */ - public Map obj2Map(Object obj) throws Exception { - Map map = new HashMap(); - Field[] fields = obj.getClass().getDeclaredFields(); - for (Field field : fields) { - field.setAccessible(true); - map.put(field.getName(), field.get(obj)); - } - return map; - } - - /** - * 流程完成时间处理 - * - * @param ms - * @return - */ - private String getDate(long ms) { - - long day = ms / (24 * 60 * 60 * 1000); - long hour = (ms / (60 * 60 * 1000) - day * 24); - long minute = ((ms / (60 * 1000)) - day * 24 * 60 - hour * 60); - long second = (ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60); - - if (day > 0) { - return day + "天" + hour + "小时" + minute + "分钟"; - } - if (hour > 0) { - return hour + "小时" + minute + "分钟"; - } - if (minute > 0) { - return minute + "分钟"; - } - if (second > 0) { - return second + "秒"; - } else { - return 0 + "秒"; - } - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysDeployFormServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysDeployFormServiceImpl.java deleted file mode 100644 index d3e0e090..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysDeployFormServiceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.ruoyi.flowable.service.impl; - -import java.util.List; -import java.util.Objects; - -import com.ruoyi.system.domain.SysForm; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.system.mapper.SysDeployFormMapper; -import com.ruoyi.system.domain.SysDeployForm; -import com.ruoyi.flowable.service.ISysDeployFormService; - -/** - * 流程实例关联表单Service业务层处理 - * - * @author Tony - * @date 2021-04-03 - */ -@Service -public class SysDeployFormServiceImpl implements ISysDeployFormService -{ - @Autowired - private SysDeployFormMapper sysDeployFormMapper; - - /** - * 查询流程实例关联表单 - * - * @param id 流程实例关联表单ID - * @return 流程实例关联表单 - */ - @Override - public SysDeployForm selectSysDeployFormById(Long id) - { - return sysDeployFormMapper.selectSysDeployFormById(id); - } - - /** - * 查询流程实例关联表单列表 - * - * @param sysDeployForm 流程实例关联表单 - * @return 流程实例关联表单 - */ - @Override - public List selectSysDeployFormList(SysDeployForm sysDeployForm) - { - return sysDeployFormMapper.selectSysDeployFormList(sysDeployForm); - } - - /** - * 新增流程实例关联表单 - * - * @param sysDeployForm 流程实例关联表单 - * @return 结果 - */ - @Override - public int insertSysDeployForm(SysDeployForm sysDeployForm) - { - SysForm sysForm = sysDeployFormMapper.selectSysDeployFormByDeployId(sysDeployForm.getDeployId()); - if (Objects.isNull(sysForm)) { - return sysDeployFormMapper.insertSysDeployForm(sysDeployForm); - }else { - return 1; - } - } - - /** - * 修改流程实例关联表单 - * - * @param sysDeployForm 流程实例关联表单 - * @return 结果 - */ - @Override - public int updateSysDeployForm(SysDeployForm sysDeployForm) - { - return sysDeployFormMapper.updateSysDeployForm(sysDeployForm); - } - - /** - * 批量删除流程实例关联表单 - * - * @param ids 需要删除的流程实例关联表单ID - * @return 结果 - */ - @Override - public int deleteSysDeployFormByIds(Long[] ids) - { - return sysDeployFormMapper.deleteSysDeployFormByIds(ids); - } - - /** - * 删除流程实例关联表单信息 - * - * @param id 流程实例关联表单ID - * @return 结果 - */ - @Override - public int deleteSysDeployFormById(Long id) - { - return sysDeployFormMapper.deleteSysDeployFormById(id); - } - - /** - * 查询流程挂着的表单 - * - * @param deployId - * @return - */ - @Override - public SysForm selectSysDeployFormByDeployId(String deployId) { - return sysDeployFormMapper.selectSysDeployFormByDeployId(deployId); - } -} diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysFormServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysFormServiceImpl.java deleted file mode 100644 index 5209fe14..00000000 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/SysFormServiceImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.ruoyi.flowable.service.impl; - -import java.util.List; -import com.ruoyi.common.utils.DateUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.system.mapper.SysFormMapper; -import com.ruoyi.system.domain.SysForm; -import com.ruoyi.flowable.service.ISysFormService; - -/** - * 流程表单Service业务层处理 - * - * @author Tony - * @date 2021-04-03 - */ -@Service -public class SysFormServiceImpl implements ISysFormService -{ - @Autowired - private SysFormMapper sysFormMapper; - - /** - * 查询流程表单 - * - * @param formId 流程表单ID - * @return 流程表单 - */ - @Override - public SysForm selectSysFormById(Long formId) - { - return sysFormMapper.selectSysFormById(formId); - } - - /** - * 查询流程表单列表 - * - * @param sysForm 流程表单 - * @return 流程表单 - */ - @Override - public List selectSysFormList(SysForm sysForm) - { - return sysFormMapper.selectSysFormList(sysForm); - } - - /** - * 新增流程表单 - * - * @param sysForm 流程表单 - * @return 结果 - */ - @Override - public int insertSysForm(SysForm sysForm) - { - sysForm.setCreateTime(DateUtils.getNowDate()); - return sysFormMapper.insertSysForm(sysForm); - } - - /** - * 修改流程表单 - * - * @param sysForm 流程表单 - * @return 结果 - */ - @Override - public int updateSysForm(SysForm sysForm) - { - sysForm.setUpdateTime(DateUtils.getNowDate()); - return sysFormMapper.updateSysForm(sysForm); - } - - /** - * 批量删除流程表单 - * - * @param formIds 需要删除的流程表单ID - * @return 结果 - */ - @Override - public int deleteSysFormByIds(Long[] formIds) - { - return sysFormMapper.deleteSysFormByIds(formIds); - } - - /** - * 删除流程表单信息 - * - * @param formId 流程表单ID - * @return 结果 - */ - @Override - public int deleteSysFormById(Long formId) - { - return sysFormMapper.deleteSysFormById(formId); - } -} diff --git a/ruoyi-mill/pom.xml b/ruoyi-mill/pom.xml new file mode 100644 index 00000000..7b241615 --- /dev/null +++ b/ruoyi-mill/pom.xml @@ -0,0 +1,24 @@ + + + + ruoyi + com.ruoyi + 3.8.9 + + 4.0.0 + jar + ruoyi-mill + + 冷轧双机架二级控制系统业务模块 + + + + + com.ruoyi + ruoyi-framework + + + + diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillPlanController.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillPlanController.java new file mode 100644 index 00000000..50e31b5d --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillPlanController.java @@ -0,0 +1,52 @@ +package com.ruoyi.mill.controller; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.mill.domain.MillPlan; +import com.ruoyi.mill.service.IMillPlanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/mill/plan") +public class MillPlanController extends BaseController { + + @Autowired + private IMillPlanService millPlanService; + + @PreAuthorize("@ss.hasPermi('mill:plan:list')") + @GetMapping("/list") + public TableDataInfo list(MillPlan query) { + startPage(); + List list = millPlanService.selectMillPlanList(query); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('mill:plan:query')") + @GetMapping("/{planNo}") + public AjaxResult getInfo(@PathVariable String planNo) { + return AjaxResult.success(millPlanService.selectMillPlanByPlanNo(planNo)); + } + + @PreAuthorize("@ss.hasPermi('mill:plan:add')") + @PostMapping + public AjaxResult add(@RequestBody MillPlan plan) { + return toAjax(millPlanService.insertMillPlan(plan)); + } + + @PreAuthorize("@ss.hasPermi('mill:plan:edit')") + @PutMapping + public AjaxResult edit(@RequestBody MillPlan plan) { + return toAjax(millPlanService.updateMillPlan(plan)); + } + + @PreAuthorize("@ss.hasPermi('mill:plan:cancel')") + @PutMapping("/cancel/{planNo}/{matSeqNo}") + public AjaxResult cancel(@PathVariable String planNo, @PathVariable String matSeqNo) { + return toAjax(millPlanService.cancelMillPlan(planNo, matSeqNo)); + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillProductionController.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillProductionController.java new file mode 100644 index 00000000..c575e11e --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/controller/MillProductionController.java @@ -0,0 +1,52 @@ +package com.ruoyi.mill.controller; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.mill.domain.MillProductionResult; +import com.ruoyi.mill.service.IMillProductionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/mill/production") +public class MillProductionController extends BaseController { + + @Autowired + private IMillProductionService productionService; + + @PreAuthorize("@ss.hasPermi('mill:production:list')") + @GetMapping("/list") + public TableDataInfo list(MillProductionResult query) { + startPage(); + List list = productionService.selectResultList(query); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('mill:production:query')") + @GetMapping("/{id}") + public AjaxResult getInfo(@PathVariable Long id) { + return AjaxResult.success(productionService.selectResultById(id)); + } + + /** 录入产出结果并自动通过 UDP 上报 K12F03 */ + @PreAuthorize("@ss.hasPermi('mill:production:add')") + @PostMapping + public AjaxResult add(@RequestBody MillProductionResult result) { + return toAjax(productionService.saveAndReport(result)); + } + + /** 删除计划钢卷并发送 K12F02 */ + @PreAuthorize("@ss.hasPermi('mill:production:delete')") + @DeleteMapping("/coil") + public AjaxResult deleteCoil(@RequestParam String planNo, + @RequestParam Integer seqNo, + @RequestParam String unitCode, + @RequestParam String inMatNo, + @RequestParam String causeDesc) { + return toAjax(productionService.deleteCoilAndNotify(planNo, seqNo, unitCode, inMatNo, causeDesc)); + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillPlan.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillPlan.java new file mode 100644 index 00000000..dcfa5978 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillPlan.java @@ -0,0 +1,128 @@ +package com.ruoyi.mill.domain; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; +import java.math.BigDecimal; + +/** + * 冷轧生产计划 — 对应 2FK101 作业命令信息 + */ +public class MillPlan extends BaseEntity { + + @Excel(name = "计划号") + private String planNo; + + @Excel(name = "序号") + private String matSeqNo; + + @Excel(name = "机组代码") + private String unitCode; + + @Excel(name = "计划类型") + private String planType; + + /** 计划状态: 0-待生产 1-生产中 2-完成 3-撤销 */ + @Excel(name = "计划状态") + private Integer planStatus; + + @Excel(name = "入口钢卷号") + private String inMatNo; + + @Excel(name = "入口厚度(mm)") + private BigDecimal inMatThick; + + @Excel(name = "入口最大厚度(mm)") + private BigDecimal inMatThickMax; + + @Excel(name = "入口最小厚度(mm)") + private BigDecimal inMatThickMin; + + @Excel(name = "入口宽度(mm)") + private BigDecimal inMatWidth; + + @Excel(name = "入口重量(t)") + private BigDecimal inMatWt; + + @Excel(name = "入口长度(m)") + private BigDecimal inMatLen; + + @Excel(name = "入口内径(mm)") + private BigDecimal inMatInDia; + + @Excel(name = "入口外径(mm)") + private BigDecimal inMatDia; + + @Excel(name = "炉号") + private String pono; + + @Excel(name = "钢种") + private String sgSign; + + @Excel(name = "出口材料号") + private String outMatNo; + + @Excel(name = "内部钢卷号") + private String custInMatNo; + + @Excel(name = "备注") + private String remark; + + // ---- getters / setters ---- + + public String getPlanNo() { return planNo; } + public void setPlanNo(String v) { this.planNo = v; } + + public String getMatSeqNo() { return matSeqNo; } + public void setMatSeqNo(String v) { this.matSeqNo = v; } + + public String getUnitCode() { return unitCode; } + public void setUnitCode(String v) { this.unitCode = v; } + + public String getPlanType() { return planType; } + public void setPlanType(String v) { this.planType = v; } + + public Integer getPlanStatus() { return planStatus; } + public void setPlanStatus(Integer v) { this.planStatus = v; } + + public String getInMatNo() { return inMatNo; } + public void setInMatNo(String v) { this.inMatNo = v; } + + public BigDecimal getInMatThick() { return inMatThick; } + public void setInMatThick(BigDecimal v) { this.inMatThick = v; } + + public BigDecimal getInMatThickMax() { return inMatThickMax; } + public void setInMatThickMax(BigDecimal v) { this.inMatThickMax = v; } + + public BigDecimal getInMatThickMin() { return inMatThickMin; } + public void setInMatThickMin(BigDecimal v) { this.inMatThickMin = v; } + + public BigDecimal getInMatWidth() { return inMatWidth; } + public void setInMatWidth(BigDecimal v) { this.inMatWidth = v; } + + public BigDecimal getInMatWt() { return inMatWt; } + public void setInMatWt(BigDecimal v) { this.inMatWt = v; } + + public BigDecimal getInMatLen() { return inMatLen; } + public void setInMatLen(BigDecimal v) { this.inMatLen = v; } + + public BigDecimal getInMatInDia() { return inMatInDia; } + public void setInMatInDia(BigDecimal v) { this.inMatInDia = v; } + + public BigDecimal getInMatDia() { return inMatDia; } + public void setInMatDia(BigDecimal v) { this.inMatDia = v; } + + public String getPono() { return pono; } + public void setPono(String v) { this.pono = v; } + + public String getSgSign() { return sgSign; } + public void setSgSign(String v) { this.sgSign = v; } + + public String getOutMatNo() { return outMatNo; } + public void setOutMatNo(String v) { this.outMatNo = v; } + + public String getCustInMatNo() { return custInMatNo; } + public void setCustInMatNo(String v) { this.custInMatNo = v; } + + public String getRemark() { return remark; } + public void setRemark(String v) { this.remark = v; } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillProductionResult.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillProductionResult.java new file mode 100644 index 00000000..9ffde85c --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/domain/MillProductionResult.java @@ -0,0 +1,158 @@ +package com.ruoyi.mill.domain; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; +import java.math.BigDecimal; + +/** + * 冷轧产出信息 — 对应 K12F03 生产信息电文 + */ +public class MillProductionResult extends BaseEntity { + + /** 操作标识: I-新增 U-修改 D-删除 */ + @Excel(name = "操作标识") + private String flag; + + @Excel(name = "计划号") + private String planNo; + + @Excel(name = "序号") + private Integer seqNo; + + @Excel(name = "机组代码") + private String unitCode; + + @Excel(name = "产出序号") + private String procSeqNo; + + @Excel(name = "产出类型") + private String annealFlag; + + @Excel(name = "入口钢卷号") + private String inMatNo; + + @Excel(name = "入口重量(t)") + private Integer inMatWt; + + @Excel(name = "入口厚度(mm)") + private BigDecimal inMatThick; + + @Excel(name = "入口宽度(mm)") + private BigDecimal inMatWidth; + + @Excel(name = "出口钢卷号") + private String outMatNo; + + @Excel(name = "内部钢卷号") + private String custMatNo; + + @Excel(name = "出口实际重量(t)") + private Integer outMatActWt; + + @Excel(name = "出口实际厚度(mm)") + private BigDecimal outMatActThick; + + @Excel(name = "出口实际宽度(mm)") + private BigDecimal outMatActWidth; + + @Excel(name = "出口实际长度(m)") + private BigDecimal outMatActLen; + + @Excel(name = "出口内径(mm)") + private BigDecimal outMatActInnerDia; + + @Excel(name = "出口外径(mm)") + private BigDecimal outMatActOuterDia; + + @Excel(name = "生产班次") + private String prodShiftNo; + + @Excel(name = "生产班组") + private String prodShiftGroup; + + @Excel(name = "开始时刻") + private String startProdTime; + + @Excel(name = "结束时刻") + private String endProdTime; + + @Excel(name = "炉台号") + private String socketNo; + + @Excel(name = "备注") + private String remark; + + // ---- getters / setters ---- + + public String getFlag() { return flag; } + public void setFlag(String v) { this.flag = v; } + + public String getPlanNo() { return planNo; } + public void setPlanNo(String v) { this.planNo = v; } + + public Integer getSeqNo() { return seqNo; } + public void setSeqNo(Integer v) { this.seqNo = v; } + + public String getUnitCode() { return unitCode; } + public void setUnitCode(String v) { this.unitCode = v; } + + public String getProcSeqNo() { return procSeqNo; } + public void setProcSeqNo(String v) { this.procSeqNo = v; } + + public String getAnnealFlag() { return annealFlag; } + public void setAnnealFlag(String v) { this.annealFlag = v; } + + public String getInMatNo() { return inMatNo; } + public void setInMatNo(String v) { this.inMatNo = v; } + + public Integer getInMatWt() { return inMatWt; } + public void setInMatWt(Integer v) { this.inMatWt = v; } + + public BigDecimal getInMatThick() { return inMatThick; } + public void setInMatThick(BigDecimal v) { this.inMatThick = v; } + + public BigDecimal getInMatWidth() { return inMatWidth; } + public void setInMatWidth(BigDecimal v) { this.inMatWidth = v; } + + public String getOutMatNo() { return outMatNo; } + public void setOutMatNo(String v) { this.outMatNo = v; } + + public String getCustMatNo() { return custMatNo; } + public void setCustMatNo(String v) { this.custMatNo = v; } + + public Integer getOutMatActWt() { return outMatActWt; } + public void setOutMatActWt(Integer v) { this.outMatActWt = v; } + + public BigDecimal getOutMatActThick() { return outMatActThick; } + public void setOutMatActThick(BigDecimal v) { this.outMatActThick = v; } + + public BigDecimal getOutMatActWidth() { return outMatActWidth; } + public void setOutMatActWidth(BigDecimal v) { this.outMatActWidth = v; } + + public BigDecimal getOutMatActLen() { return outMatActLen; } + public void setOutMatActLen(BigDecimal v) { this.outMatActLen = v; } + + public BigDecimal getOutMatActInnerDia() { return outMatActInnerDia; } + public void setOutMatActInnerDia(BigDecimal v) { this.outMatActInnerDia = v; } + + public BigDecimal getOutMatActOuterDia() { return outMatActOuterDia; } + public void setOutMatActOuterDia(BigDecimal v) { this.outMatActOuterDia = v; } + + public String getProdShiftNo() { return prodShiftNo; } + public void setProdShiftNo(String v) { this.prodShiftNo = v; } + + public String getProdShiftGroup() { return prodShiftGroup; } + public void setProdShiftGroup(String v) { this.prodShiftGroup = v; } + + public String getStartProdTime() { return startProdTime; } + public void setStartProdTime(String v) { this.startProdTime = v; } + + public String getEndProdTime() { return endProdTime; } + public void setEndProdTime(String v) { this.endProdTime = v; } + + public String getSocketNo() { return socketNo; } + public void setSocketNo(String v) { this.socketNo = v; } + + public String getRemark() { return remark; } + public void setRemark(String v) { this.remark = v; } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/FieldDef.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/FieldDef.java new file mode 100644 index 00000000..4a1751da --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/FieldDef.java @@ -0,0 +1,26 @@ +package com.ruoyi.mill.protocol; + +/** + * 电文字段描述符(与 Excel 字段定义一一对应) + */ +public class FieldDef { + + private final String name; + private final FieldType type; + /** 字符型长度(字节数);整型固定4,浮点固定4,长整型固定8 */ + private final int length; + /** 浮点精度(仅用于格式化输出,编解码不依赖此值) */ + private final int precision; + + public FieldDef(String name, FieldType type, int length, int precision) { + this.name = name; + this.type = type; + this.length = length; + this.precision = precision; + } + + public String getName() { return name; } + public FieldType getType() { return type; } + public int getLength() { return type == FieldType.STRING ? length : type == FieldType.LONG ? 8 : 4; } + public int getPrecision() { return precision; } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramCodec.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramCodec.java new file mode 100644 index 00000000..bd7a1d16 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramCodec.java @@ -0,0 +1,105 @@ +package com.ruoyi.mill.protocol; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * iXComPCS UDP 电文编解码器(第18章协议) + * + * 编码规则: + * 字符型 → 固定长度,右侧以 0x20(空格) 填充,超长截断 + * 整型 → 4 字节,大端序 (BIG_ENDIAN) + * 浮点型 → 4 字节 IEEE-754,小端序 (LITTLE_ENDIAN) + * 长整型 → 8 字节,大端序 + */ +public class TelegramCodec { + + private TelegramCodec() {} + + /** 将字段 Map 按字段定义顺序序列化为字节数组 */ + public static byte[] encode(List schema, Map data) { + int totalLen = calcTotalLength(schema); + ByteBuffer buf = ByteBuffer.allocate(totalLen); + + for (FieldDef fd : schema) { + Object val = data.getOrDefault(fd.getName(), defaultValue(fd)); + switch (fd.getType()) { + case STRING: { + String s = val == null ? "" : val.toString(); + byte[] bytes = s.getBytes(StandardCharsets.US_ASCII); + byte[] fixed = new byte[fd.getLength()]; + Arrays.fill(fixed, (byte) 0x20); + System.arraycopy(bytes, 0, fixed, 0, Math.min(bytes.length, fixed.length)); + buf.put(fixed); + break; + } + case INT: { + int i = val instanceof Number ? ((Number) val).intValue() : 0; + buf.order(ByteOrder.BIG_ENDIAN).putInt(i); + break; + } + case FLOAT: { + float f = val instanceof Number ? ((Number) val).floatValue() : 0f; + buf.order(ByteOrder.LITTLE_ENDIAN).putFloat(f); + break; + } + case LONG: { + long l = val instanceof Number ? ((Number) val).longValue() : 0L; + buf.order(ByteOrder.BIG_ENDIAN).putLong(l); + break; + } + } + } + return buf.array(); + } + + /** 将字节数组按字段定义顺序反序列化为字段 Map */ + public static Map decode(List schema, byte[] raw) { + ByteBuffer buf = ByteBuffer.wrap(raw); + Map result = new LinkedHashMap<>(); + + for (FieldDef fd : schema) { + if (buf.remaining() < fd.getLength()) break; + switch (fd.getType()) { + case STRING: { + byte[] bytes = new byte[fd.getLength()]; + buf.get(bytes); + String s = new String(bytes, StandardCharsets.US_ASCII).stripTrailing(); + result.put(fd.getName(), s); + break; + } + case INT: { + result.put(fd.getName(), buf.order(ByteOrder.BIG_ENDIAN).getInt()); + break; + } + case FLOAT: { + result.put(fd.getName(), buf.order(ByteOrder.LITTLE_ENDIAN).getFloat()); + break; + } + case LONG: { + result.put(fd.getName(), buf.order(ByteOrder.BIG_ENDIAN).getLong()); + break; + } + } + } + return result; + } + + private static int calcTotalLength(List schema) { + return schema.stream().mapToInt(FieldDef::getLength).sum(); + } + + private static Object defaultValue(FieldDef fd) { + switch (fd.getType()) { + case INT: return 0; + case FLOAT: return 0.0f; + case LONG: return 0L; + default: return ""; + } + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramField.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramField.java new file mode 100644 index 00000000..f2ba7fc2 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramField.java @@ -0,0 +1,15 @@ +package com.ruoyi.mill.protocol; + +/** + * iXComPCS 电文字段类型定义(对应 Sheet2 编码规则) + * 字符型: 空格右填充的定长 ASCII 字符串 + * 整型: 4字节有符号整数,大端序 + * 浮点型: 4字节 IEEE-754 单精度,小端序 + * 长整型: 8字节有符号整数,大端序 + */ +public enum FieldType { + STRING, // 字符型 ' ' + INT, // 整型 '>' + FLOAT, // 浮点型 '<' + LONG // 长整型 '|' +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramSchema.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramSchema.java new file mode 100644 index 00000000..71888fe0 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/protocol/TelegramSchema.java @@ -0,0 +1,192 @@ +package com.ruoyi.mill.protocol; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.ruoyi.mill.protocol.FieldType.*; + +/** + * 7 条电文的字段 Schema 定义(与 电文/*.xlsx 完全对应) + * + * L3→L2(接收): + * 2FK101 作业命令信息 + * 2FK102 作业命令撤销 + * 2FK103 作业命令应答 + * 2FK104 产出信息应答 + * + * L2→L3(发送): + * K12F01 计划信息应答 + * K12F02 计划钢卷删除 + * K12F03 生产信息电文 + */ +public final class TelegramSchema { + + private TelegramSchema() {} + + private static FieldDef s(String name, int len) { return new FieldDef(name, STRING, len, 0); } + private static FieldDef i(String name) { return new FieldDef(name, INT, 4, 0); } + private static FieldDef f(String name, int len, int precision) { return new FieldDef(name, FLOAT, len, precision); } + + // ───────────────────────────────────────────────────────────── + // 2FK101 作业命令信息 L3→L2 + // ───────────────────────────────────────────────────────────── + public static final String ID_2FK101 = "2FK101"; + public static final List SCHEMA_2FK101 = Collections.unmodifiableList(Arrays.asList( + s("PLAN_NO", 20), + s("MAT_SEQ_NO", 3), + s("UNIT_CODE", 4), + s("PLAN_TYPE", 1), + s("IN_MAT_NO", 20), + f("IN_MAT_THICK", 9, 3), + f("IN_MAT_THICK_MAX", 9, 3), + f("IN_MAT_THICK_MIN", 9, 3), + f("IN_MAT_WIDTH", 10, 3), + f("IN_MAT_WT", 5, 0), + f("IN_MAT_LEN", 12, 3), + f("IN_MAT_IN_DIA", 8, 2), + f("IN_MAT_DIA", 8, 2), + s("PONO", 10), + s("SG_SIGN", 24), + s("OUT_MAT_NO", 20), + s("CUST_IN_MAT_NO", 20), + s("REMARK", 250), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20), + f("SPARE_6", 13, 3), + f("SPARE_7", 13, 3), + f("SPARE_8", 13, 3), + f("SPARE_9", 13, 3), + f("SPARE_10", 13, 3) + )); + + // ───────────────────────────────────────────────────────────── + // 2FK102 作业命令撤销 L3→L2 + // ───────────────────────────────────────────────────────────── + public static final String ID_2FK102 = "2FK102"; + public static final List SCHEMA_2FK102 = Collections.unmodifiableList(Arrays.asList( + s("PLAN_NO", 20), + i("MAT_SEQ_NO"), + s("UNIT_CODE", 4), + s("IN_MAT_NO", 20), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); + + // ───────────────────────────────────────────────────────────── + // 2FK103 作业命令应答 L3→L2 + // ───────────────────────────────────────────────────────────── + public static final String ID_2FK103 = "2FK103"; + public static final List SCHEMA_2FK103 = Collections.unmodifiableList(Arrays.asList( + s("TC_NO", 6), + s("PLAN_NO", 20), + i("SEQ_NO"), + s("UNIT_CODE", 4), + s("IN_MAT_NO", 20), + s("FLAG", 1), + s("DEAL_RESULT", 50), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); + + // ───────────────────────────────────────────────────────────── + // 2FK104 产出信息应答 L3→L2 + // ───────────────────────────────────────────────────────────── + public static final String ID_2FK104 = "2FK104"; + public static final List SCHEMA_2FK104 = Collections.unmodifiableList(Arrays.asList( + s("TC_NO", 6), + s("PLAN_NO", 20), + i("SEQ_NO"), + s("UNIT_CODE", 4), + s("OUT_MAT_NO", 20), + s("FLAG", 1), + s("DEAL_RESULT", 50), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); + + // ───────────────────────────────────────────────────────────── + // K12F01 计划信息应答 L2→L3 + // ───────────────────────────────────────────────────────────── + public static final String ID_K12F01 = "K12F01"; + public static final List SCHEMA_K12F01 = Collections.unmodifiableList(Arrays.asList( + s("TC_NO", 6), + s("PLAN_NO", 20), + i("SEQ_NO"), + s("UNIT_CODE", 4), + s("IN_MAT_NO", 20), + s("FLAG", 1), + s("DEAL_RESULT", 50), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); + + // ───────────────────────────────────────────────────────────── + // K12F02 计划钢卷删除 L2→L3 + // ───────────────────────────────────────────────────────────── + public static final String ID_K12F02 = "K12F02"; + public static final List SCHEMA_K12F02 = Collections.unmodifiableList(Arrays.asList( + s("PLAN_NO", 20), + i("SEQ_NO"), + s("UNIT_CODE", 4), + s("IN_MAT_NO", 20), + s("CAUSE_DESC", 50), + s("DO_TIME", 14), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); + + // ───────────────────────────────────────────────────────────── + // K12F03 生产信息电文 L2→L3 + // ───────────────────────────────────────────────────────────── + public static final String ID_K12F03 = "K12F03"; + public static final List SCHEMA_K12F03 = Collections.unmodifiableList(Arrays.asList( + s("FLAG", 1), + s("PLAN_NO", 20), + i("SEQ_NO"), + s("UNIT_CODE", 4), + s("PROC_SEQ_NO", 4), + s("ANNEAL_FLAG", 16), + s("IN_MAT_NO", 20), + i("IN_MAT_WT"), + f("IN_MAT_THICK", 9, 3), + f("IN_MAT_WIDTH", 10, 3), + s("OUT_MAT_NO", 20), + s("CUST_MAT_NO", 20), + i("OUT_MAT_ACT_WT"), + f("OUT_MAT_ACT_THICK", 9, 3), + f("OUT_MAT_ACT_WIDTH", 10, 3), + f("OUT_MAT_ACT_LEN", 15, 3), + f("OUT_MAT_ACT_INNER_DIA", 8, 2), + f("OUT_MAT_ACT_OUTER_DIA", 8, 2), + s("PROD_SHIFT_NO", 1), + s("PROD_SHIFT_GROUP", 1), + s("START_PROD_TIME", 14), + s("END_PROD_TIME", 14), + s("SOCKET_NO", 2), + s("REMARK", 100), + s("SPARE_1", 20), + s("SPARE_2", 20), + s("SPARE_3", 20), + s("SPARE_4", 20), + s("SPARE_5", 20) + )); +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillPlanService.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillPlanService.java new file mode 100644 index 00000000..35722f68 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillPlanService.java @@ -0,0 +1,18 @@ +package com.ruoyi.mill.service; + +import com.ruoyi.mill.domain.MillPlan; +import java.util.List; + +public interface IMillPlanService { + + List selectMillPlanList(MillPlan query); + + MillPlan selectMillPlanByPlanNo(String planNo); + + int insertMillPlan(MillPlan plan); + + int updateMillPlan(MillPlan plan); + + /** 撤销计划(L3 下发 2FK102 后调用) */ + int cancelMillPlan(String planNo, String matSeqNo); +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillProductionService.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillProductionService.java new file mode 100644 index 00000000..b604b94a --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/IMillProductionService.java @@ -0,0 +1,18 @@ +package com.ruoyi.mill.service; + +import com.ruoyi.mill.domain.MillProductionResult; +import java.util.List; + +public interface IMillProductionService { + + List selectResultList(MillProductionResult query); + + MillProductionResult selectResultById(Long id); + + /** 保存产出并通过 UDP 发送 K12F03 */ + int saveAndReport(MillProductionResult result); + + /** 删除计划钢卷并发送 K12F02 */ + int deleteCoilAndNotify(String planNo, Integer seqNo, String unitCode, + String inMatNo, String causeDesc); +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillPlanServiceImpl.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillPlanServiceImpl.java new file mode 100644 index 00000000..ad7bd419 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillPlanServiceImpl.java @@ -0,0 +1,64 @@ +package com.ruoyi.mill.service.impl; + +import com.ruoyi.mill.domain.MillPlan; +import com.ruoyi.mill.service.IMillPlanService; +import com.ruoyi.mill.udp.UdpSender; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class MillPlanServiceImpl implements IMillPlanService { + + @Autowired + private UdpSender udpSender; + + // TODO: 注入 MillPlanMapper 并替换以下占位实现 + + @Override + public List selectMillPlanList(MillPlan query) { + return new ArrayList<>(); + } + + @Override + public MillPlan selectMillPlanByPlanNo(String planNo) { + return null; + } + + @Override + public int insertMillPlan(MillPlan plan) { + // TODO: mapper.insert(plan) + // 写入成功后回复 K12F01 计划信息应答 + sendK12F01Ack(plan.getPlanNo(), plan.getMatSeqNo(), + plan.getUnitCode(), plan.getInMatNo(), "1", "OK"); + return 1; + } + + @Override + public int updateMillPlan(MillPlan plan) { + return 0; // TODO + } + + @Override + public int cancelMillPlan(String planNo, String matSeqNo) { + // TODO: mapper 软删除 + return 1; + } + + private void sendK12F01Ack(String planNo, String seqNo, String unitCode, + String inMatNo, String flag, String dealResult) { + Map data = new HashMap<>(); + data.put("TC_NO", "K12F01"); + data.put("PLAN_NO", planNo); + data.put("SEQ_NO", 0); + data.put("UNIT_CODE", unitCode); + data.put("IN_MAT_NO", inMatNo); + data.put("FLAG", flag); + data.put("DEAL_RESULT", dealResult); + udpSender.sendK12F01(data); + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillProductionServiceImpl.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillProductionServiceImpl.java new file mode 100644 index 00000000..501f3d33 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/service/impl/MillProductionServiceImpl.java @@ -0,0 +1,83 @@ +package com.ruoyi.mill.service.impl; + +import com.ruoyi.mill.domain.MillProductionResult; +import com.ruoyi.mill.service.IMillProductionService; +import com.ruoyi.mill.udp.UdpSender; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class MillProductionServiceImpl implements IMillProductionService { + + private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + + @Autowired + private UdpSender udpSender; + + // TODO: 注入 MillProductionResultMapper + + @Override + public List selectResultList(MillProductionResult query) { + return new ArrayList<>(); + } + + @Override + public MillProductionResult selectResultById(Long id) { + return null; + } + + @Override + public int saveAndReport(MillProductionResult r) { + // TODO: mapper.insert(r) + // 保存成功后发送 K12F03 + Map data = new HashMap<>(); + data.put("FLAG", "I"); + data.put("PLAN_NO", r.getPlanNo()); + data.put("SEQ_NO", r.getSeqNo() == null ? 0 : r.getSeqNo()); + data.put("UNIT_CODE", r.getUnitCode()); + data.put("PROC_SEQ_NO", r.getProcSeqNo()); + data.put("ANNEAL_FLAG", r.getAnnealFlag()); + data.put("IN_MAT_NO", r.getInMatNo()); + data.put("IN_MAT_WT", r.getInMatWt() == null ? 0 : r.getInMatWt()); + data.put("IN_MAT_THICK", r.getInMatThick() == null ? 0f : r.getInMatThick().floatValue()); + data.put("IN_MAT_WIDTH", r.getInMatWidth() == null ? 0f : r.getInMatWidth().floatValue()); + data.put("OUT_MAT_NO", r.getOutMatNo()); + data.put("CUST_MAT_NO", r.getCustMatNo()); + data.put("OUT_MAT_ACT_WT", r.getOutMatActWt() == null ? 0 : r.getOutMatActWt()); + data.put("OUT_MAT_ACT_THICK", r.getOutMatActThick() == null ? 0f : r.getOutMatActThick().floatValue()); + data.put("OUT_MAT_ACT_WIDTH", r.getOutMatActWidth() == null ? 0f : r.getOutMatActWidth().floatValue()); + data.put("OUT_MAT_ACT_LEN", r.getOutMatActLen() == null ? 0f : r.getOutMatActLen().floatValue()); + data.put("OUT_MAT_ACT_INNER_DIA", r.getOutMatActInnerDia() == null ? 0f : r.getOutMatActInnerDia().floatValue()); + data.put("OUT_MAT_ACT_OUTER_DIA", r.getOutMatActOuterDia() == null ? 0f : r.getOutMatActOuterDia().floatValue()); + data.put("PROD_SHIFT_NO", r.getProdShiftNo()); + data.put("PROD_SHIFT_GROUP", r.getProdShiftGroup()); + data.put("START_PROD_TIME", r.getStartProdTime()); + data.put("END_PROD_TIME", r.getEndProdTime()); + data.put("SOCKET_NO", r.getSocketNo()); + data.put("REMARK", r.getRemark()); + udpSender.sendK12F03(data); + return 1; + } + + @Override + public int deleteCoilAndNotify(String planNo, Integer seqNo, String unitCode, + String inMatNo, String causeDesc) { + // TODO: mapper 软删除 + Map data = new HashMap<>(); + data.put("PLAN_NO", planNo); + data.put("SEQ_NO", seqNo == null ? 0 : seqNo); + data.put("UNIT_CODE", unitCode); + data.put("IN_MAT_NO", inMatNo); + data.put("CAUSE_DESC", causeDesc); + data.put("DO_TIME", LocalDateTime.now().format(FMT)); + udpSender.sendK12F02(data); + return 1; + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/TelegramDispatcher.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/TelegramDispatcher.java new file mode 100644 index 00000000..8c327810 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/TelegramDispatcher.java @@ -0,0 +1,66 @@ +package com.ruoyi.mill.udp; + +import com.ruoyi.mill.protocol.TelegramCodec; +import com.ruoyi.mill.protocol.TelegramSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 接收到的 L3→L2 电文分发处理器 + * 根据电文号前6字节路由到对应业务处理方法 + */ +@Component +public class TelegramDispatcher { + + private static final Logger log = LoggerFactory.getLogger(TelegramDispatcher.class); + + public void dispatch(String telegramId, byte[] payload) { + log.info("[UDP-RECV] telegramId={} payloadLen={}", telegramId, payload.length); + switch (telegramId) { + case TelegramSchema.ID_2FK101: + handle2FK101(TelegramCodec.decode(TelegramSchema.SCHEMA_2FK101, payload)); + break; + case TelegramSchema.ID_2FK102: + handle2FK102(TelegramCodec.decode(TelegramSchema.SCHEMA_2FK102, payload)); + break; + case TelegramSchema.ID_2FK103: + handle2FK103(TelegramCodec.decode(TelegramSchema.SCHEMA_2FK103, payload)); + break; + case TelegramSchema.ID_2FK104: + handle2FK104(TelegramCodec.decode(TelegramSchema.SCHEMA_2FK104, payload)); + break; + default: + log.warn("[UDP-RECV] 未知电文号: {}", telegramId); + } + } + + /** 2FK101 作业命令信息 — L3 下发生产计划 */ + private void handle2FK101(Map data) { + log.info("[2FK101] 作业命令: planNo={} inMatNo={} unitCode={}", + data.get("PLAN_NO"), data.get("IN_MAT_NO"), data.get("UNIT_CODE")); + // TODO: 写入计划表,触发 K12F01 应答 + } + + /** 2FK102 作业命令撤销 — L3 撤销某条计划 */ + private void handle2FK102(Map data) { + log.info("[2FK102] 作业撤销: planNo={} inMatNo={}", data.get("PLAN_NO"), data.get("IN_MAT_NO")); + // TODO: 从计划表软删除,记录撤销原因 + } + + /** 2FK103 作业命令应答 — L3 对 L2 发出计划的回执 */ + private void handle2FK103(Map data) { + log.info("[2FK103] 命令应答: tcNo={} flag={} result={}", + data.get("TC_NO"), data.get("FLAG"), data.get("DEAL_RESULT")); + // TODO: 更新计划状态 + } + + /** 2FK104 产出信息应答 — L3 对 L2 上报产出的回执 */ + private void handle2FK104(Map data) { + log.info("[2FK104] 产出应答: tcNo={} flag={} result={}", + data.get("TC_NO"), data.get("FLAG"), data.get("DEAL_RESULT")); + // TODO: 更新产出确认状态 + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpProperties.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpProperties.java new file mode 100644 index 00000000..22afce98 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpProperties.java @@ -0,0 +1,33 @@ +package com.ruoyi.mill.udp; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * UDP 通信参数配置(application.yml: mill.udp.*) + */ +@Component +@ConfigurationProperties(prefix = "mill.udp") +public class UdpProperties { + + /** 本地监听端口(接收 L3 下发电文) */ + private int localPort = 9001; + + /** L3 系统 IP */ + private String remoteHost = "127.0.0.1"; + + /** L3 系统端口 */ + private int remotePort = 9000; + + /** 接收缓冲区大小(字节) */ + private int bufferSize = 4096; + + public int getLocalPort() { return localPort; } + public void setLocalPort(int p) { this.localPort = p; } + public String getRemoteHost() { return remoteHost; } + public void setRemoteHost(String h){ this.remoteHost = h; } + public int getRemotePort() { return remotePort; } + public void setRemotePort(int p) { this.remotePort = p; } + public int getBufferSize() { return bufferSize; } + public void setBufferSize(int s) { this.bufferSize = s; } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpSender.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpSender.java new file mode 100644 index 00000000..66448c95 --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpSender.java @@ -0,0 +1,62 @@ +package com.ruoyi.mill.udp; + +import com.ruoyi.mill.protocol.TelegramCodec; +import com.ruoyi.mill.protocol.TelegramSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Map; + +/** + * UDP 发送服务 — L2→L3 上行电文 + * 帧结构:前6字节电文号 + 电文体 + */ +@Component +public class UdpSender { + + private static final Logger log = LoggerFactory.getLogger(UdpSender.class); + + @Autowired + private UdpProperties props; + + /** K12F01 计划信息应答 */ + public void sendK12F01(Map data) { + send(TelegramSchema.ID_K12F01, TelegramCodec.encode(TelegramSchema.SCHEMA_K12F01, data)); + } + + /** K12F02 计划钢卷删除 */ + public void sendK12F02(Map data) { + send(TelegramSchema.ID_K12F02, TelegramCodec.encode(TelegramSchema.SCHEMA_K12F02, data)); + } + + /** K12F03 生产信息电文 */ + public void sendK12F03(Map data) { + send(TelegramSchema.ID_K12F03, TelegramCodec.encode(TelegramSchema.SCHEMA_K12F03, data)); + } + + private void send(String tcNo, byte[] payload) { + try (DatagramSocket socket = new DatagramSocket()) { + // 帧 = 6字节电文号 + payload + byte[] tcNoBytes = Arrays.copyOf( + tcNo.getBytes(StandardCharsets.US_ASCII), 6); + byte[] frame = new byte[6 + payload.length]; + System.arraycopy(tcNoBytes, 0, frame, 0, 6); + System.arraycopy(payload, 0, frame, 6, payload.length); + + InetAddress addr = InetAddress.getByName(props.getRemoteHost()); + DatagramPacket pkt = new DatagramPacket(frame, frame.length, addr, props.getRemotePort()); + socket.send(pkt); + log.info("[UDP-SEND] tcNo={} -> {}:{} frameLen={}", tcNo, + props.getRemoteHost(), props.getRemotePort(), frame.length); + } catch (Exception e) { + log.error("[UDP-SEND] 发送失败 tcNo={}", tcNo, e); + } + } +} diff --git a/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpServer.java b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpServer.java new file mode 100644 index 00000000..a241104a --- /dev/null +++ b/ruoyi-mill/src/main/java/com/ruoyi/mill/udp/UdpServer.java @@ -0,0 +1,77 @@ +package com.ruoyi.mill.udp; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * UDP 接收服务 + * 监听来自 L3 的下行电文,解析电文号后交 TelegramDispatcher 处理 + * + * 电文帧结构(iXComPCS 第18章): + * 前6字节 ASCII = 电文号 (TC_NO) + * 后续字节 = 电文体 (payload) + */ +@Component +public class UdpServer { + + private static final Logger log = LoggerFactory.getLogger(UdpServer.class); + private static final int TC_NO_LEN = 6; + + @Autowired + private UdpProperties props; + + @Autowired + private TelegramDispatcher dispatcher; + + private DatagramSocket socket; + private volatile boolean running; + private final ExecutorService executor = Executors.newSingleThreadExecutor( + r -> { Thread t = new Thread(r, "udp-receiver"); t.setDaemon(true); return t; }); + + @PostConstruct + public void start() throws Exception { + socket = new DatagramSocket(props.getLocalPort()); + running = true; + executor.submit(this::receiveLoop); + log.info("[UDP-SERVER] 已启动,监听端口: {}", props.getLocalPort()); + } + + @PreDestroy + public void stop() { + running = false; + if (socket != null && !socket.isClosed()) socket.close(); + executor.shutdownNow(); + log.info("[UDP-SERVER] 已停止"); + } + + private void receiveLoop() { + byte[] buf = new byte[props.getBufferSize()]; + while (running) { + try { + DatagramPacket pkt = new DatagramPacket(buf, buf.length); + socket.receive(pkt); + byte[] data = Arrays.copyOf(pkt.getData(), pkt.getLength()); + if (data.length < TC_NO_LEN) { + log.warn("[UDP-SERVER] 收到过短数据包,长度={}", data.length); + continue; + } + String tcNo = new String(data, 0, TC_NO_LEN, StandardCharsets.US_ASCII).trim(); + byte[] payload = Arrays.copyOfRange(data, TC_NO_LEN, data.length); + dispatcher.dispatch(tcNo, payload); + } catch (Exception e) { + if (running) log.error("[UDP-SERVER] 接收异常", e); + } + } + } +} diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss index 5bf2fbb1..dff3b0bd 100644 --- a/ruoyi-ui/src/assets/styles/element-variables.scss +++ b/ruoyi-ui/src/assets/styles/element-variables.scss @@ -1,31 +1,122 @@ -/** -* I think element-ui's default theme color is too light for long-term use. -* So I modified the default color and you can modify it to your liking. -**/ - -/* theme color */ -$--color-primary: #1890ff; -$--color-success: #13ce66; -$--color-warning: #ffba00; -$--color-danger: #ff4949; -// $--color-info: #1E1E1E; - -$--button-font-weight: 400; - -// $--color-text-regular: #1f2d3d; - -$--border-color-light: #dfe4ed; -$--border-color-lighter: #e6ebf5; - -$--table-border: 1px solid #dfe6ec; - -/* icon font path, required */ -$--font-path: '~element-ui/lib/theme-chalk/fonts'; - -@import "~element-ui/packages/theme-chalk/src/index"; - -// the :export directive is the magic sauce for webpack -// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass -:export { - theme: $--color-primary; -} +/** + * 冷轧二级控制系统 — Element-UI 主题覆盖(工业风格) + */ + +/* 主题色:工业青蓝 */ +$--color-primary: #0099cc; +$--color-success: #00c853; +$--color-warning: #ff8c00; +$--color-danger: #ff3d00; +$--color-info: #546e8a; + +$--button-font-weight: 500; + +/* 边框 */ +$--border-color-light: #1a3a5c; +$--border-color-lighter: #152e4a; + +$--table-border: 1px solid #1a3a5c; + +/* icon font path */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "~element-ui/packages/theme-chalk/src/index"; + +// 深色背景下全局 Element 样式覆盖 +.el-table { + background-color: #0e2137 !important; + color: #c8d8e8 !important; + + th.el-table__cell { + background-color: #0a1e35 !important; + color: #00d4ff !important; + border-bottom: 1px solid #1a3a5c !important; + font-size: 13px; + font-weight: 600; + letter-spacing: 0.5px; + } + + td.el-table__cell { + border-bottom: 1px solid #132030 !important; + } + + tr:hover > td { + background-color: #122840 !important; + } + + &::before { + background-color: #1a3a5c; + } +} + +.el-card { + background-color: #0e2137 !important; + border: 1px solid #1a3a5c !important; + border-radius: 4px; + color: #c8d8e8; + + .el-card__header { + border-bottom: 1px solid #1a3a5c; + color: #00d4ff; + font-weight: 600; + font-size: 14px; + padding: 12px 20px; + } +} + +.el-input__inner { + background-color: #071120 !important; + border-color: #1a3a5c !important; + color: #c8d8e8 !important; + &::placeholder { color: #4a6a8a; } + &:focus { border-color: #00d4ff !important; } +} + +.el-select .el-input__inner { background-color: #071120 !important; } + +.el-dropdown-menu, +.el-select-dropdown { + background-color: #0e2137 !important; + border: 1px solid #1a3a5c !important; + .el-select-dropdown__item { color: #c8d8e8 !important; } + .el-select-dropdown__item.hover, + .el-select-dropdown__item:hover { background-color: #0a2545 !important; } + .el-select-dropdown__item.selected { color: #00d4ff !important; } +} + +.el-pagination { + color: #8ab0cc !important; + .btn-prev, .btn-next, .el-pager li { + background-color: #0e2137 !important; + color: #8ab0cc !important; + border: 1px solid #1a3a5c !important; + } + .el-pager li.active { color: #00d4ff !important; border-color: #00d4ff !important; } +} + +.el-dialog { + background-color: #0e2137 !important; + border: 1px solid #1a3a5c; + .el-dialog__title { color: #00d4ff !important; } + .el-dialog__body { color: #c8d8e8 !important; } +} + +.el-form-item__label { color: #8ab0cc !important; } + +.el-tag { + &.el-tag--success { background-color: rgba(0,200,83,.15); border-color: #00c853; color: #00c853; } + &.el-tag--danger { background-color: rgba(255,61,0,.15); border-color: #ff3d00; color: #ff3d00; } + &.el-tag--warning { background-color: rgba(255,140,0,.15); border-color: #ff8c00; color: #ff8c00; } + &.el-tag--info { background-color: rgba(84,110,138,.15);border-color: #546e8a; color: #8ab0cc; } +} + +.el-button--primary { + background-color: #0077aa !important; + border-color: #0099cc !important; + &:hover { background-color: #0099cc !important; } +} + +// webpack JS/SCSS 变量共享 +:export { + theme: $--color-primary; +} diff --git a/ruoyi-ui/src/assets/styles/index.scss b/ruoyi-ui/src/assets/styles/index.scss index 1dd82920..860577f6 100644 --- a/ruoyi-ui/src/assets/styles/index.scss +++ b/ruoyi-ui/src/assets/styles/index.scss @@ -5,132 +5,192 @@ @import './sidebar.scss'; @import './btn.scss'; +// 工业风全局字体与背景 body { height: 100%; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; + margin: 0; + background-color: #071120; + color: $industrial-text; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Microsoft YaHei', + 'Source Han Sans CN', Arial, monospace; + font-size: 14px; } -label { - font-weight: 700; -} +label { font-weight: 600; color: #8ab0cc; } html { height: 100%; box-sizing: border-box; } -#app { - height: 100%; -} +#app { height: 100%; } -*, -*:before, -*:after { - box-sizing: inherit; -} +*, *:before, *:after { box-sizing: inherit; } -.no-padding { - padding: 0px !important; -} - -.padding-content { - padding: 4px 0; -} - -a:focus, -a:active { - outline: none; -} - -a, -a:focus, -a:hover { +a:focus, a:active { outline: none; } +a, a:focus, a:hover { cursor: pointer; - color: inherit; + color: $industrial-cyan; text-decoration: none; } -div:focus { - outline: none; -} +div:focus { outline: none; } -.fr { - float: right; -} +// 工具类 +.fr { float: right; } +.fl { float: left; } +.pr-5 { padding-right: 5px; } +.pl-5 { padding-left: 5px; } +.block { display: block; } +.pointer { cursor: pointer; } +.inlineBlock { display: block; } +.text-center { text-align: center; } +.no-padding { padding: 0 !important; } +.padding-content { padding: 4px 0; } -.fl { - float: left; -} - -.pr-5 { - padding-right: 5px; -} - -.pl-5 { - padding-left: 5px; -} - -.block { +.clearfix:after { + visibility: hidden; display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; } -.pointer { - cursor: pointer; +// 页面内容容器 +.app-container { + padding: 16px 20px; + background-color: transparent; } -.inlineBlock { - display: block; -} +// 搜索/过滤栏 +.filter-container { + padding-bottom: 12px; + background-color: $industrial-surface; + padding: 12px 16px; + border: 1px solid $industrial-border; + border-radius: 4px; + margin-bottom: 12px; -.clearfix { - &:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 8px; + margin-right: 8px; } } -aside { - background: #eef1f6; - padding: 8px 24px; - margin-bottom: 20px; - border-radius: 2px; - display: block; - line-height: 32px; - font-size: 16px; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: #2c3e50; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; +// 状态徽标 — 机组运行状态 +.status-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 6px; - a { - color: #337ab7; - cursor: pointer; + &.running { background-color: $industrial-green; box-shadow: 0 0 6px $industrial-green; } + &.stopped { background-color: $industrial-red; box-shadow: 0 0 6px $industrial-red; } + &.standby { background-color: $industrial-amber; box-shadow: 0 0 6px $industrial-amber; } + &.offline { background-color: $industrial-text-muted; } +} - &:hover { - color: rgb(32, 160, 255); +// 数据看板 — 工艺参数数值框 +.param-value { + font-family: 'Courier New', Courier, monospace; + font-size: 20px; + font-weight: 700; + color: $industrial-cyan; + letter-spacing: 1px; +} + +.param-unit { + font-size: 11px; + color: $industrial-text-muted; + margin-left: 4px; +} + +// 告警闪烁 +@keyframes alarmBlink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.3; } +} + +.alarm-blink { + animation: alarmBlink 1s ease-in-out infinite; + color: $industrial-red; +} + +// 顶部导航栏 +.navbar { + background-color: #091628 !important; + border-bottom: 1px solid #00d4ff33 !important; + box-shadow: 0 2px 12px rgba(0, 212, 255, 0.08) !important; +} + +// 面包屑 +.el-breadcrumb__inner { color: #6b8aaa !important; } +.el-breadcrumb__inner.is-link:hover { color: #00d4ff !important; } +.el-breadcrumb__separator { color: #1a3a5c !important; } + +// 标签页(tab-view) +.tags-view-container { + background-color: #071120 !important; + border-bottom: 1px solid #1a3a5c !important; + + .tags-view-wrapper .tags-view-item { + background-color: #0e2137 !important; + border: 1px solid #1a3a5c !important; + color: #8ab0cc !important; + + &.active { + background-color: #0077aa !important; + border-color: #00d4ff !important; + color: #ffffff !important; } } } -//main-container全局样式 -.app-container { - padding: 20px; +// 侧边栏 Logo 区域 +.sidebar-logo-container { + background-color: #060f1e !important; + border-bottom: 1px solid #1a3a5c !important; + + .sidebar-title { + color: #00d4ff !important; + font-size: 16px !important; + font-weight: 700 !important; + letter-spacing: 1px; + } } -.components-container { - margin: 30px 50px; - position: relative; +// 滚动条工业风格 +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: #071120; } +::-webkit-scrollbar-thumb { background: #1a3a5c; border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: #00d4ff55; } + +// 提示/备注区域 +aside { + background: #0e2137; + padding: 8px 16px; + margin-bottom: 16px; + border-left: 3px solid #00d4ff; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 13px; + color: #8ab0cc; + + a { color: #00d4ff; &:hover { color: #40e0ff; } } } -.text-center { - text-align: center +.link-type, .link-type:focus { + color: #00d4ff; + cursor: pointer; + &:hover { color: #40e0ff; } } .sub-navbar { @@ -140,48 +200,17 @@ aside { width: 100%; text-align: right; padding-right: 20px; - transition: 600ms ease position; - background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + background: linear-gradient(90deg, #0a1e35 0%, #0077aa 100%); + border-bottom: 1px solid #00d4ff44; - .subtitle { - font-size: 20px; - color: #fff; - } - - &.draft { - background: #d0d0d0; - } - - &.deleted { - background: #d0d0d0; - } + .subtitle { font-size: 16px; color: #fff; letter-spacing: 1px; } } -.link-type, -.link-type:focus { - color: #337ab7; - cursor: pointer; - - &:hover { - color: rgb(32, 160, 255); - } +.components-container { + margin: 20px 30px; + position: relative; } -.filter-container { - padding-bottom: 10px; - - .filter-item { - display: inline-block; - vertical-align: middle; - margin-bottom: 10px; - } -} - -//refine vue-multiselect plugin -.multiselect { - line-height: 16px; -} - -.multiselect--active { - z-index: 1000 !important; -} +// 多选 +.multiselect { line-height: 16px; } +.multiselect--active { z-index: 1000 !important; } diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss index 9f390460..9c94c493 100644 --- a/ruoyi-ui/src/assets/styles/sidebar.scss +++ b/ruoyi-ui/src/assets/styles/sidebar.scss @@ -76,11 +76,12 @@ white-space: nowrap !important; } - // menu hover + // menu hover — 工业风高亮 .submenu-title-noDropdown, .el-submenu__title { &:hover { - background-color: rgba(0, 0, 0, 0.06) !important; + background-color: rgba(0, 212, 255, 0.08) !important; + border-left: 2px solid #00d4ff; } } @@ -88,12 +89,18 @@ color: $base-menu-color-active !important; } + .el-menu-item.is-active { + background-color: rgba(0, 119, 170, 0.30) !important; + border-left: 3px solid #00d4ff !important; + color: #00d4ff !important; + } + & .nest-menu .el-submenu>.el-submenu__title, & .el-submenu .el-menu-item { min-width: $base-sidebar-width !important; &:hover { - background-color: rgba(0, 0, 0, 0.06) !important; + background-color: rgba(0, 212, 255, 0.08) !important; } } diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss index 8715dc78..3e595d88 100644 --- a/ruoyi-ui/src/assets/styles/variables.scss +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -1,54 +1,53 @@ -// base color -$blue:#324157; -$light-blue:#3A71A8; -$red:#C03639; -$pink: #E65D6E; -$green: #30B08F; -$tiffany: #4AB7BD; -$yellow:#FEC171; -$panGreen: #30B08F; - -// 默认菜单主题风格 -$base-menu-color:#bfcbd9; -$base-menu-color-active:#f4f4f5; -$base-menu-background:#304156; -$base-logo-title-color: #ffffff; - -$base-menu-light-color:rgba(0,0,0,.70); -$base-menu-light-background:#ffffff; -$base-logo-light-title-color: #001529; - -$base-sub-menu-background:#1f2d3d; -$base-sub-menu-hover:#001528; - -// 自定义暗色菜单风格 -/** -$base-menu-color:hsla(0,0%,100%,.65); -$base-menu-color-active:#fff; -$base-menu-background:#001529; -$base-logo-title-color: #ffffff; - -$base-menu-light-color:rgba(0,0,0,.70); -$base-menu-light-background:#ffffff; -$base-logo-light-title-color: #001529; - -$base-sub-menu-background:#000c17; -$base-sub-menu-hover:#001528; -*/ - -$base-sidebar-width: 200px; - -// the :export directive is the magic sauce for webpack -// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass -:export { - menuColor: $base-menu-color; - menuLightColor: $base-menu-light-color; - menuColorActive: $base-menu-color-active; - menuBackground: $base-menu-background; - menuLightBackground: $base-menu-light-background; - subMenuBackground: $base-sub-menu-background; - subMenuHover: $base-sub-menu-hover; - sideBarWidth: $base-sidebar-width; - logoTitleColor: $base-logo-title-color; - logoLightTitleColor: $base-logo-light-title-color -} +// ============================================================ +// 冷轧双机架二级控制系统 — 工业深色主题色板 +// ============================================================ + +// btn.scss 依赖的旧变量(映射到工业色板) +$blue: #0099cc; +$light-blue:#00d4ff; +$red: #ff3d00; +$pink: #ff6b6b; +$green: #00c853; +$tiffany: #00b4d8; +$yellow: #ff8c00; +$panGreen: #00c853; + +// 工业色调 +$industrial-bg: #0a1628; // 深海军蓝,主背景 +$industrial-surface: #0e2137; // 卡片/面板背景 +$industrial-border: #1a3a5c; // 边框色 +$industrial-cyan: #00d4ff; // 工业青色,主高亮 +$industrial-amber: #ff8c00; // 琥珀橙,警告/重点 +$industrial-green: #00e676; // 状态绿,正常/运行 +$industrial-red: #ff3d00; // 告警红 +$industrial-text: #c8d8e8; // 主文字 +$industrial-text-muted: #6b8aaa; // 次要文字 + +// 默认侧边栏主题(工业深色) +$base-menu-color: #8ab0cc; +$base-menu-color-active: #00d4ff; +$base-menu-background: #0a1628; +$base-logo-title-color: #e0f0ff; + +$base-menu-light-color: rgba(0,0,0,.70); +$base-menu-light-background: #ffffff; +$base-logo-light-title-color:#001529; + +$base-sub-menu-background: #071120; +$base-sub-menu-hover: #0d2040; + +$base-sidebar-width: 210px; + +// webpack JS/SCSS 变量共享 +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color; +} diff --git a/ruoyi-ui/src/settings.js b/ruoyi-ui/src/settings.js index 059c74d7..ac0358ab 100644 --- a/ruoyi-ui/src/settings.js +++ b/ruoyi-ui/src/settings.js @@ -1,44 +1,46 @@ -module.exports = { - /** - * 侧边栏主题 深色主题theme-dark,浅色主题theme-light - */ - sideTheme: 'theme-dark', - - /** - * 是否系统布局配置 - */ - showSettings: false, - - /** - * 是否显示顶部导航 - */ - topNav: false, - - /** - * 是否显示 tagsView - */ - tagsView: true, - - /** - * 是否固定头部 - */ - fixedHeader: false, - - /** - * 是否显示logo - */ - sidebarLogo: true, - - /** - * 是否显示动态标题 - */ - dynamicTitle: false, - - /** - * @type {string | array} 'production' | ['production', 'development'] - * @description Need show err logs component. - * The default is only used in the production env - * If you want to also use it in dev, you can pass ['production', 'development'] - */ - errorLog: 'production' -} +module.exports = { + /** + * 网站标题 + */ + title: '冷轧双机架二级控制系统', + + /** + * 侧边栏主题:固定使用工业深色主题 + */ + sideTheme: 'theme-dark', + + /** + * 是否显示右上角设置按钮(生产环境建议关闭) + */ + showSettings: false, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView(多标签页) + */ + tagsView: true, + + /** + * 是否固定头部 + */ + fixedHeader: true, + + /** + * 是否显示侧边栏 Logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: true, + + /** + * 错误日志显示环境 + */ + errorLog: 'production' +} diff --git a/sql/README.md b/sql/README.md deleted file mode 100644 index 7c9c573a..00000000 --- a/sql/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## 数据库导入说明 -依次执行 - ry_xxx.sql 脚本 - quartz.sql 脚本 - tony-flowable.sql 脚本 diff --git a/sql/tony-flowable.sql b/sql/tony-flowable.sql deleted file mode 100644 index 3adb300d..00000000 --- a/sql/tony-flowable.sql +++ /dev/null @@ -1,110 +0,0 @@ --- sys_deploy_form definition - -CREATE TABLE `sys_deploy_form` -( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', - `form_id` bigint(20) DEFAULT NULL COMMENT '表单主键', - `deploy_id` varchar(50) DEFAULT NULL COMMENT '流程实例主键', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=9623 DEFAULT CHARSET=utf8mb4 COMMENT='流程实例关联表单'; - --- sys_expression definition - -CREATE TABLE `sys_expression` -( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表单主键', - `name` varchar(50) DEFAULT NULL COMMENT '表达式名称', - `expression` varchar(255) DEFAULT NULL COMMENT '表达式内容', - `data_type` varchar(255) DEFAULT NULL COMMENT '表达式类型', - `create_time` datetime DEFAULT NULL COMMENT '创建时间', - `update_time` datetime DEFAULT NULL COMMENT '更新时间', - `create_by` bigint(20) DEFAULT NULL COMMENT '创建人员', - `update_by` bigint(20) DEFAULT NULL COMMENT '更新人员', - `status` tinyint(2) DEFAULT '0' COMMENT '状态', - `remark` varchar(255) DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8mb4 COMMENT='流程表达式'; - - --- sys_form definition - -CREATE TABLE `sys_form` -( - `form_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表单主键', - `form_name` varchar(50) DEFAULT NULL COMMENT '表单名称', - `form_content` longtext COMMENT '表单内容', - `create_time` datetime DEFAULT NULL COMMENT '创建时间', - `update_time` datetime DEFAULT NULL COMMENT '更新时间', - `create_by` bigint(20) DEFAULT NULL COMMENT '创建人员', - `update_by` bigint(20) DEFAULT NULL COMMENT '更新人员', - `remark` varchar(255) DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`form_id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=3936 DEFAULT CHARSET=utf8mb4 COMMENT='流程表单'; - - --- sys_listener definition - -CREATE TABLE `sys_listener` -( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '表单主键', - `name` varchar(128) DEFAULT NULL COMMENT '名称', - `type` char(2) DEFAULT NULL COMMENT '监听类型', - `event_type` varchar(32) DEFAULT NULL COMMENT '事件类型', - `value_type` varchar(32) DEFAULT NULL COMMENT '值类型', - `value` varchar(255) DEFAULT NULL COMMENT '执行内容', - `create_time` datetime DEFAULT NULL COMMENT '创建时间', - `update_time` datetime DEFAULT NULL COMMENT '更新时间', - `create_by` bigint(20) DEFAULT NULL COMMENT '创建人员', - `update_by` bigint(20) DEFAULT NULL COMMENT '更新人员', - `status` tinyint(2) DEFAULT '0' COMMENT '状态', - `remark` varchar(255) DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='流程监听'; - - --- 流程相关菜单 -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2020, '流程管理', 0, 6, 'flowable', NULL, NULL, NULL, 1, 0, 'M', '0', '0', '', 'cascader', 'tony', '2021-03-25 11:35:09', 'admin', '2022-12-29 17:39:22', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2022, '流程定义', 2020, 2, 'definition', 'flowable/definition/index', NULL, NULL, 1, 0, 'C', '0', '0', '', 'job', 'tony', '2021-03-25 13:53:55', 'admin', '2022-12-29 17:40:39', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2023, '任务管理', 0, 7, 'task', NULL, NULL, NULL, 1, 0, 'M', '0', '0', '', 'dict', 'tony', '2021-03-26 10:53:10', 'admin', '2021-03-29 09:37:40', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2024, '待办任务', 2023, 2, 'todo', 'flowable/task/todo/index', NULL, NULL, 1, 1, 'C', '0', '0', '', 'cascader', 'admin', '2021-03-26 10:55:52', 'admin', '2021-03-30 09:26:36', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2025, '已办任务', 2023, 3, 'finished', 'flowable/task/finished/index', NULL, NULL, 1, 1, 'C', '0', '0', '', 'time-range', 'admin', '2021-03-26 10:57:54', 'admin', '2021-03-30 09:26:50', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2026, '已发任务', 2023, 1, 'process', 'flowable/task/myProcess/index', NULL, NULL, 1, 1, 'C', '0', '0', '', 'guide', 'admin', '2021-03-30 09:26:23', 'admin', '2022-12-12 09:58:07', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2027, '表单配置', 2020, 2, 'form', 'flowable/task/form/index', NULL, NULL, 1, 1, 'C', '0', '0', 'flowable:form:list', 'form', 'admin', '2021-03-30 22:55:12', 'admin', '2023-08-19 15:54:57', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2028, '新增', 2027, 1, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'flowable:form:add', '#', 'admin', '2021-07-07 14:23:37', 'admin', '2023-08-16 09:17:38', ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2029, '删除', 2027, 3, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'flowable:form:remove', '#', 'admin', '2021-07-07 14:24:10', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2030, '编辑', 2027, 2, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'flowable:form:edit', '#', 'admin', '2021-07-07 14:24:31', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2031, '新增', 2026, 1, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'system:deployment:add', '#', 'admin', '2021-07-07 14:25:22', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2032, '编辑', 2026, 2, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'system:deployment:edit', '#', 'admin', '2021-07-07 14:25:47', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2033, '删除', 2026, 3, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'system:deployment:remove', '#', 'admin', '2021-07-07 14:26:02', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2034, '查询', 2027, 4, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'flowable:form:query', '#', 'admin', '2021-07-08 14:05:22', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2035, '修改密码', 100, 8, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'system:user:updatePwd', '#', 'admin', '2022-04-29 11:27:13', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2036, '流程表达式', 2020, 3, 'expression', 'flowable/expression/index', NULL, NULL, 1, 1, 'C', '0', '0', 'system:expression:list', 'list', 'admin', '2022-12-12 17:12:19', 'admin', '2022-12-12 17:13:44', '流程达式菜单'); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2037, '流程达式查询', 2036, 1, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:expression:query', '#', 'admin', '2022-12-12 17:12:19', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2038, '流程达式新增', 2036, 2, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:expression:add', '#', 'admin', '2022-12-12 17:12:19', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2039, '流程达式修改', 2036, 3, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:expression:edit', '#', 'admin', '2022-12-12 17:12:19', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2040, '流程达式删除', 2036, 4, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:expression:remove', '#', 'admin', '2022-12-12 17:12:19', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2041, '流程达式导出', 2036, 5, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:expression:export', '#', 'admin', '2022-12-12 17:12:19', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2042, '流程监听', 2020, 4, 'listener', 'flowable/listener/index', NULL, NULL, 1, 0, 'C', '0', '0', 'system:listener:list', 'monitor', 'admin', '2022-12-25 11:44:16', 'admin', '2022-12-29 08:59:21', '流程监听菜单'); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2043, '流程监听查询', 2042, 1, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:listener:query', '#', 'admin', '2022-12-25 11:44:16', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2044, '流程监听新增', 2042, 2, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:listener:add', '#', 'admin', '2022-12-25 11:44:16', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2045, '流程监听修改', 2042, 3, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:listener:edit', '#', 'admin', '2022-12-25 11:44:16', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2046, '流程监听删除', 2042, 4, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:listener:remove', '#', 'admin', '2022-12-25 11:44:16', '', NULL, ''); -INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, `path`, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES(2047, '流程监听导出', 2042, 5, '#', '', NULL, NULL, 1, 0, 'F', '0', '0', 'system:listener:export', '#', 'admin', '2022-12-25 11:44:16', '', NULL, ''); - --- 流程相关字段表信息 -INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, update_by, update_time, remark) VALUES(100, '表达式类型', 'exp_data_type', '0', 'admin', '2024-03-12 09:03:02', '', NULL, NULL); -INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, update_by, update_time, remark) VALUES(102, '监听类型', 'sys_listener_type', '0', 'admin', '2022-12-18 22:03:07', '', NULL, NULL); -INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, update_by, update_time, remark) VALUES(103, '监听值类型', 'sys_listener_value_type', '0', 'admin', '2022-12-18 22:03:39', '', NULL, NULL); -INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, update_by, update_time, remark) VALUES(104, '监听属性', 'sys_listener_event_type', '0', 'admin', '2022-12-18 22:04:29', '', NULL, NULL); -INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, update_by, update_time, remark) VALUES(105, '流程分类', 'sys_process_category', '0', 'admin', '2024-03-12 09:08:18', '', NULL, NULL); - - -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(100, 0, '系统指定', 'fixed', 'exp_data_type', NULL, 'default', 'N', '0', 'admin', '2024-03-12 09:04:46', '', NULL, NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(101, 0, '动态选择', 'dynamic', 'exp_data_type', NULL, 'default', 'N', '0', 'admin', '2024-03-12 09:05:02', '', NULL, NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(104, 0, '任务监听', '1', 'sys_listener_type', NULL, 'default', 'N', '0', 'admin', '2022-12-25 11:47:26', '', NULL, NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(105, 2, '执行监听', '2', 'sys_listener_type', NULL, 'default', 'N', '0', 'admin', '2022-12-25 11:47:37', '', NULL, NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(106, 0, 'JAVA类', 'classListener', 'sys_listener_value_type', NULL, 'default', 'N', '0', 'admin', '2022-12-25 11:48:55', 'admin', '2024-09-05 21:38:02', NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(107, 0, '表达式', 'expressionListener', 'sys_listener_value_type', NULL, 'default', 'N', '0', 'admin', '2022-12-25 11:49:05', 'admin', '2024-09-05 21:38:10', NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(108, 0, '代理表达式', 'delegateExpressionListener', 'sys_listener_value_type', NULL, 'default', 'N', '0', 'admin', '2022-12-25 11:49:16', 'admin', '2024-09-05 21:38:16', NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(109, 0, '请假', 'leave', 'sys_process_category', NULL, 'default', 'N', '0', 'admin', '2024-03-12 09:08:42', '', NULL, NULL); -INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, update_by, update_time, remark) VALUES(110, 0, '报销', 'expense', 'sys_process_category', NULL, 'default', 'N', '0', 'admin', '2024-03-12 09:09:02', '', NULL, NULL);