| | |
| | | # è
¾è®¯äº sms.tencentcloudapi.com |
| | | endpoint: "dysmsapi.aliyuncs.com" |
| | | accessKeyId: xxxxxxx |
| | | accessKeySecret: xxxxxx |
| | | accessKeySecret: xxxxxxq |
| | | signName: æµè¯ |
| | | # è
¾è®¯ä¸ç¨ |
| | | sdkAppId: |
| | | # =============================== |
| | | # Flowable é
ç½®ï¼éæ Flowable æ¶å¯ç¨ï¼ |
| | | # =============================== |
| | | flowable: |
| | | database-schema-update: true # 馿¬¡è¿è¡å»ºè®®ä¸º trueï¼åæè®¾ä¸º false |
| | | async-executor-activate: false |
| | | id-generator: simple |
| | | |
| | | |
| | |
| | | stdio: |
| | | servers-configuration: classpath:mcp-server.json |
| | | request-timeout: 300s |
| | | |
| | |
| | | * |
| | | */ |
| | | void updateXcxUser(SysUserBo user); |
| | | |
| | | List<SysUser> selectUserByRoleIds(List<Long> groups); |
| | | |
| | | List<SysUser> selectUserByDeptIds(List<Long> groups); |
| | | } |
| | |
| | | package org.ruoyi.system.service; |
| | | |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.core.page.PageQuery; |
| | | import org.ruoyi.core.page.TableDataInfo; |
| | | import org.ruoyi.system.domain.SysUser; |
| | |
| | | */ |
| | | int deleteUserByIds(Long[] userIds); |
| | | |
| | | R<List<SysUser>> selectUserByRoleIds(List<Long> groups); |
| | | |
| | | R<List<SysUser>> selectUserByDeptIds(List<Long> groups); |
| | | } |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.constant.CacheNames; |
| | | import org.ruoyi.common.core.constant.UserConstants; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.service.UserService; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | |
| | | .eq(SysUser::getUserName, userName)); |
| | | return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserBalance().toString(); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®è§è²ç»æ¥è¯¢ç¨æ· |
| | | */ |
| | | @Override |
| | | public R<List<SysUser>> selectUserByRoleIds(List<Long> groups) { |
| | | List<SysUser> list = baseMapper.selectUserByRoleIds(groups); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | @Override |
| | | public R<List<SysUser>> selectUserByDeptIds(List<Long> groups) { |
| | | List<SysUser> list = baseMapper.selectUserByDeptIds(groups); |
| | | return R.ok(list); |
| | | } |
| | | } |
| | |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.user_id = #{userId} |
| | | </select> |
| | | <select id="selectUserByRoleIds" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and r.role_id in <foreach item="item" collection="list" separator="," open="(" close=")" index=""> |
| | | #{item} |
| | | </foreach> |
| | | </select> |
| | | <select id="selectUserByDeptIds" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.dept_id in <foreach item="item" collection="list" separator="," open="(" close=")" index=""> |
| | | #{item} |
| | | </foreach> |
| | | </select> |
| | | |
| | | |
| | | </mapper> |
| | |
| | | <module>ruoyi-chat</module> |
| | | <module>ruoyi-system</module> |
| | | <module>ruoyi-generator</module> |
| | | <module>ruoyi-flowable</module> |
| | | </modules> |
| | | |
| | | <properties> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <artifactId>ruoyi-flowable</artifactId> |
| | | |
| | | <properties> |
| | | <maven.compiler.source>17</maven.compiler.source> |
| | | <maven.compiler.target>17</maven.compiler.target> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | <flowable.version>6.8.0</flowable.version> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <!-- Flowable 工使µ --> |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-spring-boot-starter-process</artifactId> |
| | | <version>${flowable.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- Spring Boot Web --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Lombok --> |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.googlecode.aviator</groupId> |
| | | <artifactId>aviator</artifactId> |
| | | <version>5.3.1</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-system-api</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.nimbusds</groupId> |
| | | <artifactId>oauth2-oidc-sdk</artifactId> |
| | | <version>11.10.1</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.common.constant; |
| | | |
| | | /** |
| | | * æµç¨å¸¸éä¿¡æ¯ |
| | | * |
| | | * @author Xuan xuan |
| | | * @date 2021/4/17 22:46 |
| | | */ |
| | | public class ProcessConstants { |
| | | |
| | | public static final String SUFFIX = ".bpmn"; |
| | | |
| | | /** |
| | | * å¨ææ°æ® |
| | | */ |
| | | public static final String DATA_TYPE = "dynamic"; |
| | | |
| | | /** |
| | | * å个审æ¹äºº |
| | | */ |
| | | public static final String USER_TYPE_ASSIGNEE = "assignee"; |
| | | |
| | | |
| | | /** |
| | | * åé人 |
| | | */ |
| | | public static final String USER_TYPE_USERS = "candidateUsers"; |
| | | |
| | | |
| | | /** |
| | | * 审æ¹ç» |
| | | */ |
| | | public static final String USER_TYPE_ROUPS = "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"; |
| | | |
| | | /** |
| | | * èªå®ä¹å±æ§ localScope |
| | | */ |
| | | public static final String PROCESS_FORM_LOCAL_SCOPE = "localScope"; |
| | | |
| | | /** |
| | | * èªå®ä¹å±æ§ æµç¨ç¶æ |
| | | */ |
| | | public static final String PROCESS_STATUS_KEY = "processStatus"; |
| | | |
| | | |
| | | /** |
| | | * æµç¨è·³è¿ |
| | | */ |
| | | public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED"; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.common.constant; |
| | | |
| | | /** |
| | | * @author konbai |
| | | * @createTime 2022/4/24 13:24 |
| | | */ |
| | | public class TaskConstants { |
| | | |
| | | /** |
| | | * æµç¨å起人 |
| | | */ |
| | | public static final String PROCESS_INITIATOR = "initiator"; |
| | | |
| | | /** |
| | | * è§è²åéç»åç¼ |
| | | */ |
| | | public static final String ROLE_GROUP_PREFIX = "ROLE"; |
| | | |
| | | /** |
| | | * é¨é¨åéç»åç¼ |
| | | */ |
| | | public static final String DEPT_GROUP_PREFIX = "DEPT"; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.common.enums; |
| | | |
| | | /** |
| | | * æµç¨æè§ç±»å |
| | | * |
| | | * @author Xuan xuan |
| | | * @date 2021/4/19 |
| | | */ |
| | | public enum FlowComment { |
| | | |
| | | /** |
| | | * 说æ |
| | | */ |
| | | NORMAL("1", "æ£å¸¸"), |
| | | REBACK("2", "éå"), |
| | | REJECT("3", "驳å"), |
| | | DELEGATE("4", "å§æ´¾"), |
| | | TRANSFER("5", "转å"), |
| | | STOP("6", "ç»æ¢"), |
| | | REVOKE("7", "æ¤å"); |
| | | |
| | | /** |
| | | * ç±»å |
| | | */ |
| | | 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.common.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/28 9:51 |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum FormType { |
| | | |
| | | /** |
| | | * æµç¨è¡¨å |
| | | */ |
| | | PROCESS(0), |
| | | |
| | | /** |
| | | * å¤ç½®è¡¨å |
| | | */ |
| | | EXTERNAL(1), |
| | | |
| | | /** |
| | | * èç¹ç¬ç«è¡¨å |
| | | */ |
| | | INDEPENDENT(2); |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private final Integer type; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.common.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | |
| | | /** |
| | | * @author konbai |
| | | * @since 2023/3/9 00:45 |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum ProcessStatus { |
| | | |
| | | /** |
| | | * è¿è¡ä¸ï¼å®¡æ¹ä¸ï¼ |
| | | */ |
| | | RUNNING("running"), |
| | | /** |
| | | * å·²ç»æ¢ |
| | | */ |
| | | TERMINATED("terminated"), |
| | | /** |
| | | * 已宿 |
| | | */ |
| | | COMPLETED("completed"), |
| | | /** |
| | | * 已忶 |
| | | */ |
| | | CANCELED("canceled"); |
| | | |
| | | private final String status; |
| | | |
| | | public static ProcessStatus getProcessStatus(String str) { |
| | | if (StringUtils.isNotBlank(str)) { |
| | | for (ProcessStatus value : values()) { |
| | | if (StringUtils.equalsIgnoreCase(str, value.getStatus())) { |
| | | return value; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.config; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; |
| | | import org.flowable.engine.RuntimeService; |
| | | import org.ruoyi.flowable.listener.GlobalEventListener; |
| | | import org.springframework.context.ApplicationListener; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.event.ContextRefreshedEvent; |
| | | |
| | | /** |
| | | * flowableå
¨å±çå¬é
ç½® |
| | | * |
| | | * @author ssc |
| | | */ |
| | | @Configuration |
| | | @AllArgsConstructor |
| | | public class GlobalEventListenerConfig implements ApplicationListener<ContextRefreshedEvent> { |
| | | |
| | | private final GlobalEventListener globalEventListener; |
| | | private final RuntimeService runtimeService; |
| | | |
| | | @Override |
| | | public void onApplicationEvent(ContextRefreshedEvent event) { |
| | | // æµç¨æ£å¸¸ç»æ |
| | | runtimeService.addEventListener(globalEventListener, FlowableEngineEventType.PROCESS_COMPLETED); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.config; |
| | | |
| | | 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 XuanXuan |
| | | * @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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.config; |
| | | |
| | | import cn.hutool.core.net.NetUtil; |
| | | import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.transaction.annotation.EnableTransactionManagement; |
| | | |
| | | /** |
| | | * mybatis-plusé
置类(䏿¹æ³¨éææä»¶ä»ç») |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @EnableTransactionManagement(proxyTargetClass = true) |
| | | @Configuration |
| | | public class MybatisPlusConfig { |
| | | |
| | | @Bean |
| | | public MybatisPlusInterceptor mybatisPlusInterceptor() { |
| | | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| | | // å页æä»¶ |
| | | interceptor.addInnerInterceptor(paginationInnerInterceptor()); |
| | | // ä¹è§éæä»¶ |
| | | interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor()); |
| | | return interceptor; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * å页æä»¶ï¼èªå¨è¯å«æ°æ®åºç±»å |
| | | */ |
| | | public PaginationInnerInterceptor paginationInnerInterceptor() { |
| | | PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
| | | // 设置æå¤§å页éå¶æ°éï¼é»è®¤ 500 æ¡ï¼-1 ä¸åéå¶ |
| | | paginationInnerInterceptor.setMaxLimit(-1L); |
| | | // å页åçå |
| | | paginationInnerInterceptor.setOverflow(true); |
| | | return paginationInnerInterceptor; |
| | | } |
| | | |
| | | /** |
| | | * ä¹è§éæä»¶ |
| | | */ |
| | | public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() { |
| | | return new OptimisticLockerInnerInterceptor(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 使ç¨ç½å¡ä¿¡æ¯ç»å®éªè±çæå¨ |
| | | * 鲿¢é群éªè±IDéå¤ |
| | | */ |
| | | @Bean |
| | | public IdentifierGenerator idGenerator() { |
| | | return new DefaultIdentifierGenerator(NetUtil.getLocalhost()); |
| | | } |
| | | |
| | | /** |
| | | * PaginationInnerInterceptor å页æä»¶ï¼èªå¨è¯å«æ°æ®åºç±»å |
| | | * https://baomidou.com/pages/97710a/ |
| | | * OptimisticLockerInnerInterceptor ä¹è§éæä»¶ |
| | | * https://baomidou.com/pages/0d93c0/ |
| | | * MetaObjectHandler å
å¯¹è±¡åæ®µå¡«å
æ§å¶å¨ |
| | | * https://baomidou.com/pages/4c6bcf/ |
| | | * ISqlInjector sql注å
¥å¨ |
| | | * https://baomidou.com/pages/42ea4a/ |
| | | * BlockAttackInnerInterceptor 妿æ¯å¯¹å
¨è¡¨çå é¤ææ´æ°æä½ï¼å°±ä¼ç»æ¢è¯¥æä½ |
| | | * https://baomidou.com/pages/f9a237/ |
| | | * IllegalSQLInnerInterceptor sqlæ§è½è§èæä»¶(åå¾SQLæ¦æª) |
| | | * IdentifierGenerator èªå®ä¹ä¸»é®çç¥ |
| | | * https://baomidou.com/pages/568eb2/ |
| | | * TenantLineInnerInterceptor å¤ç§æ·æä»¶ |
| | | * https://baomidou.com/pages/aef2f2/ |
| | | * DynamicTableNameInnerInterceptor å¨æè¡¨åæä»¶ |
| | | * https://baomidou.com/pages/2a45ff/ |
| | | */ |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.core; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表å屿§ç±» |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/8/6 18:54 |
| | | */ |
| | | @Data |
| | | public class FormConf { |
| | | |
| | | /** |
| | | * æ é¢ |
| | | */ |
| | | private String title; |
| | | /** |
| | | * 表åå |
| | | */ |
| | | private String formRef; |
| | | /** |
| | | * è¡¨åæ¨¡å |
| | | */ |
| | | private Map<String, Object> formModel; |
| | | /** |
| | | * 表å尺寸 |
| | | */ |
| | | private String size; |
| | | /** |
| | | * æ ç¾å¯¹é½ |
| | | */ |
| | | private String labelPosition; |
| | | /** |
| | | * æ ç¾å®½åº¦ |
| | | */ |
| | | private Integer labelWidth; |
| | | /** |
| | | * æ ¡éªæ¨¡å |
| | | */ |
| | | private String formRules; |
| | | /** |
| | | * æ
æ ¼é´é |
| | | */ |
| | | private Integer gutter; |
| | | /** |
| | | * ç¦ç¨è¡¨å |
| | | */ |
| | | private Boolean disabled = false; |
| | | /** |
| | | * æ
æ ¼å æ®çåæ° |
| | | */ |
| | | private Integer span; |
| | | /** |
| | | * 表åæé® |
| | | */ |
| | | private Boolean formBtns = true; |
| | | /** |
| | | * 表å项 |
| | | */ |
| | | private List<Map<String, Object>> fields; |
| | | /** |
| | | * è¡¨åæ°æ® |
| | | */ |
| | | private Map<String, Object> formData; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.core.domain; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨æ¥è¯¢å®ä½å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/6/11 01:15 |
| | | */ |
| | | @Data |
| | | public class ProcessQuery { |
| | | |
| | | /** |
| | | * æµç¨æ è¯ |
| | | */ |
| | | private String processKey; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | private String processName; |
| | | |
| | | /** |
| | | * æµç¨åç±» |
| | | */ |
| | | private String category; |
| | | |
| | | /** |
| | | * ç¶æ |
| | | */ |
| | | private String state; |
| | | |
| | | /** |
| | | * 请æ±åæ° |
| | | */ |
| | | private Map<String, Object> params = new HashMap<>(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.core.domain.model; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.OrderItem; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.Data; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.core.utils.sql.SqlUtil; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å®ä½ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class PageQuery implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * åé¡µå¤§å° |
| | | */ |
| | | private Integer pageSize; |
| | | |
| | | /** |
| | | * å½åé¡µæ° |
| | | */ |
| | | private Integer pageNum; |
| | | |
| | | /** |
| | | * æåºå |
| | | */ |
| | | private String orderByColumn; |
| | | |
| | | /** |
| | | * æåºçæ¹ådescæè
asc |
| | | */ |
| | | private String isAsc; |
| | | |
| | | /** |
| | | * å½åè®°å½èµ·å§ç´¢å¼ é»è®¤å¼ |
| | | */ |
| | | public static final int DEFAULT_PAGE_NUM = 1; |
| | | |
| | | /** |
| | | * æ¯é¡µæ¾ç¤ºè®°å½æ° é»è®¤å¼ é»è®¤æ¥å
¨é¨ |
| | | */ |
| | | public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; |
| | | |
| | | public <T> Page<T> build() { |
| | | Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM); |
| | | Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE); |
| | | if (pageNum <= 0) { |
| | | pageNum = DEFAULT_PAGE_NUM; |
| | | } |
| | | Page<T> page = new Page<>(pageNum, pageSize); |
| | | List<OrderItem> orderItems = buildOrderItem(); |
| | | if (CollUtil.isNotEmpty(orderItems)) { |
| | | page.addOrder(orderItems); |
| | | } |
| | | return page; |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæåº |
| | | * |
| | | * æ¯æçç¨æ³å¦ä¸: |
| | | * {isAsc:"asc",orderByColumn:"id"} order by id asc |
| | | * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc |
| | | * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc |
| | | * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc |
| | | */ |
| | | private List<OrderItem> buildOrderItem() { |
| | | if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) { |
| | | return null; |
| | | } |
| | | String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); |
| | | orderBy = StringUtils.toUnderScoreCase(orderBy); |
| | | |
| | | // å
¼å®¹å端æåºç±»å |
| | | isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); |
| | | |
| | | String[] orderByArr = orderBy.split(","); |
| | | String[] isAscArr = isAsc.split(","); |
| | | if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) { |
| | | throw new ServiceException("æåºåæ°æè¯¯"); |
| | | } |
| | | |
| | | List<OrderItem> list = new ArrayList<>(); |
| | | // æ¯ä¸ªå段åèªæåº |
| | | for (int i = 0; i < orderByArr.length; i++) { |
| | | String orderByStr = orderByArr[i]; |
| | | String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i]; |
| | | if ("asc".equals(isAscStr)) { |
| | | list.add(OrderItem.asc(orderByStr)); |
| | | } else if ("desc".equals(isAscStr)) { |
| | | list.add(OrderItem.desc(orderByStr)); |
| | | } else { |
| | | throw new ServiceException("æåºåæ°æè¯¯"); |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.core.mapper; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.toolkit.Db; |
| | | import org.apache.ibatis.logging.Log; |
| | | import org.apache.ibatis.logging.LogFactory; |
| | | import org.ruoyi.flowable.utils.BeanCopyUtils; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * èªå®ä¹ Mapper æ¥å£, å®ç° èªå®ä¹æ©å± |
| | | * |
| | | * @param <M> mapper æ³å |
| | | * @param <T> table æ³å |
| | | * @param <V> vo æ³å |
| | | * @author Lion Li |
| | | * @since 2021-05-13 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> { |
| | | |
| | | Log log = LogFactory.getLog(BaseMapperPlus.class); |
| | | |
| | | default Class<V> currentVoClass() { |
| | | return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2); |
| | | } |
| | | |
| | | default Class<T> currentModelClass() { |
| | | return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1); |
| | | } |
| | | |
| | | default Class<M> currentMapperClass() { |
| | | return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0); |
| | | } |
| | | |
| | | default List<T> selectList() { |
| | | return this.selectList(new QueryWrapper<>()); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ |
| | | */ |
| | | default boolean insertBatch(Collection<T> entityList) { |
| | | return Db.saveBatch(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ´æ° |
| | | */ |
| | | default boolean updateBatchById(Collection<T> entityList) { |
| | | return Db.updateBatchById(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ææ´æ° |
| | | */ |
| | | default boolean insertOrUpdateBatch(Collection<T> entityList) { |
| | | return Db.saveOrUpdateBatch(entityList); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertBatch(Collection<T> entityList, int batchSize) { |
| | | return Db.saveBatch(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean updateBatchById(Collection<T> entityList, int batchSize) { |
| | | return Db.updateBatchById(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæå
¥ææ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) { |
| | | return Db.saveOrUpdateBatch(entityList, batchSize); |
| | | } |
| | | |
| | | /** |
| | | * æå
¥ææ´æ°(å
å«éå¶æ¡æ°) |
| | | */ |
| | | default boolean insertOrUpdate(T entity) { |
| | | return Db.saveOrUpdate(entity); |
| | | } |
| | | |
| | | default V selectVoById(Serializable id) { |
| | | return selectVoById(id, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® ID æ¥è¯¢ |
| | | */ |
| | | default <C> C selectVoById(Serializable id, Class<C> voClass) { |
| | | T obj = this.selectById(id); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | return null; |
| | | } |
| | | return BeanCopyUtils.copy(obj, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) { |
| | | return selectVoBatchIds(idList, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ï¼æ ¹æ®ID æ¹éæ¥è¯¢ï¼ |
| | | */ |
| | | default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) { |
| | | List<T> list = this.selectBatchIds(idList); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoByMap(Map<String, Object> map) { |
| | | return selectVoByMap(map, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ï¼æ ¹æ® columnMap æ¡ä»¶ï¼ |
| | | */ |
| | | default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) { |
| | | List<T> list = this.selectByMap(map); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default V selectVoOne(Wrapper<T> wrapper) { |
| | | return selectVoOne(wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢ä¸æ¡è®°å½ |
| | | */ |
| | | default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) { |
| | | T obj = this.selectOne(wrapper); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | return null; |
| | | } |
| | | return BeanCopyUtils.copy(obj, voClass); |
| | | } |
| | | |
| | | default List<V> selectVoList(Wrapper<T> wrapper) { |
| | | return selectVoList(wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢å
¨é¨è®°å½ |
| | | */ |
| | | default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) { |
| | | List<T> list = this.selectList(wrapper); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return BeanCopyUtils.copyList(list, voClass); |
| | | } |
| | | |
| | | default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) { |
| | | return selectVoPage(page, wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢VO |
| | | */ |
| | | default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) { |
| | | IPage<T> pageData = this.selectPage(page, wrapper); |
| | | IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal()); |
| | | if (CollUtil.isEmpty(pageData.getRecords())) { |
| | | return (P) voPage; |
| | | } |
| | | voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass)); |
| | | return (P) voPage; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.core.page; |
| | | |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * è¡¨æ ¼åé¡µæ°æ®å¯¹è±¡ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class TableDataInfo<T> implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æ»è®°å½æ° |
| | | */ |
| | | private long total; |
| | | |
| | | /** |
| | | * åè¡¨æ°æ® |
| | | */ |
| | | private List<T> rows; |
| | | |
| | | /** |
| | | * æ¶æ¯ç¶æç |
| | | */ |
| | | private int code; |
| | | |
| | | /** |
| | | * æ¶æ¯å
容 |
| | | */ |
| | | private String msg; |
| | | |
| | | /** |
| | | * å页 |
| | | * |
| | | * @param list åè¡¨æ°æ® |
| | | * @param total æ»è®°å½æ° |
| | | */ |
| | | public TableDataInfo(List<T> list, long total) { |
| | | this.rows = list; |
| | | this.total = total; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build(IPage<T> page) { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | rspData.setRows(page.getRecords()); |
| | | rspData.setTotal(page.getTotal()); |
| | | return rspData; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build(List<T> list) { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | rspData.setRows(list); |
| | | rspData.setTotal(list.size()); |
| | | return rspData; |
| | | } |
| | | |
| | | public static <T> TableDataInfo<T> build() { |
| | | TableDataInfo<T> rspData = new TableDataInfo<>(); |
| | | rspData.setCode(HttpStatus.HTTP_OK); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | return rspData; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.factory; |
| | | |
| | | import jakarta.annotation.Resource; |
| | | import lombok.Getter; |
| | | import org.flowable.engine.*; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * flowable å¼ææ³¨å
¥å°è£
|
| | | * @author XuanXuan |
| | | * @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 FormService formService; |
| | | |
| | | @Resource |
| | | protected HistoryService historyService; |
| | | |
| | | @Resource |
| | | protected ManagementService managementService; |
| | | |
| | | @Qualifier("processEngine") |
| | | @Resource |
| | | protected ProcessEngine processEngine; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.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 XuanXuan |
| | | * @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) { |
| | | int sourceX = xPoints[i - 1]; |
| | | int sourceY = yPoints[i - 1]; |
| | | int targetX = xPoints[i]; |
| | | int 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.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 XuanXuan |
| | | * @date 2021/4/5 0:31 |
| | | */ |
| | | public class CustomProcessDiagramGenerator extends DefaultProcessDiagramGenerator { |
| | | @Override |
| | | protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> 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, List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, Boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | 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); |
| | | List<GraphicInfo> 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.flow; |
| | | |
| | | import com.googlecode.aviator.AviatorEvaluator; |
| | | import com.googlecode.aviator.Expression; |
| | | 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.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author Xuan xuan |
| | | * @date 2021/4/19 20:51 |
| | | */ |
| | | public class FindNextNodeUtil { |
| | | |
| | | /** |
| | | * è·åä¸ä¸æ¥éª¤çç¨æ·ä»»å¡ |
| | | * |
| | | * @param repositoryService |
| | | * @param map |
| | | * @return |
| | | */ |
| | | public static List<UserTask> getNextUserTasks(RepositoryService repositoryService, org.flowable.task.api.Task task, Map<String, Object> map) { |
| | | List<UserTask> data = new ArrayList<>(); |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); |
| | | Process mainProcess = bpmnModel.getMainProcess(); |
| | | Collection<FlowElement> flowElements = mainProcess.getFlowElements(); |
| | | String key = task.getTaskDefinitionKey(); |
| | | FlowElement flowElement = bpmnModel.getFlowElement(key); |
| | | next(flowElements, flowElement, map, data); |
| | | return data; |
| | | } |
| | | |
| | | public static void next(Collection<FlowElement> flowElements, FlowElement flowElement, Map<String, Object> map, List<UserTask> nextUser) { |
| | | //妿æ¯ç»æèç¹ |
| | | if (flowElement instanceof EndEvent) { |
| | | //妿æ¯åä»»å¡çç»æèç¹ |
| | | if (getSubProcess(flowElements, flowElement) != null) { |
| | | flowElement = getSubProcess(flowElements, flowElement); |
| | | } |
| | | } |
| | | //è·åTaskçåºçº¿ä¿¡æ¯--å¯ä»¥æ¥æå¤ä¸ª |
| | | List<SequenceFlow> 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<FlowElement> flowElements, List<UserTask> 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<FlowElement> 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<FlowElement> 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<FlowElement> flowElements) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof StartEvent) { |
| | | return flowElement; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªelè¡¨è¾¾å¼ |
| | | * |
| | | * @param map |
| | | * @param expression |
| | | * @return |
| | | */ |
| | | public static boolean expressionResult(Map<String, Object> map, String expression) { |
| | | Expression exp = AviatorEvaluator.compile(expression); |
| | | final Object execute = exp.execute(map); |
| | | return Boolean.parseBoolean(String.valueOf(execute)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.flow; |
| | | |
| | | import org.flowable.spring.SpringProcessEngineConfiguration; |
| | | import org.flowable.spring.boot.EngineConfigurationConfigurer; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | |
| | | /** |
| | | * @author XuanXuan |
| | | * @date 2021/4/5 01:32 |
| | | */ |
| | | @Configuration |
| | | public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> { |
| | | |
| | | @Override |
| | | public void configure(SpringProcessEngineConfiguration engineConfiguration) { |
| | | engineConfiguration.setActivityFontName("å®ä½"); |
| | | engineConfiguration.setLabelFontName("å®ä½"); |
| | | engineConfiguration.setAnnotationFontName("å®ä½"); |
| | | |
| | | } |
| | | } |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.flow; |
| | | |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; |
| | | import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author XuanXuan |
| | | * @date 2021-04-03 23:57 |
| | | */ |
| | | @Slf4j |
| | | public class FlowableUtils { |
| | | |
| | | /** |
| | | * æ ¹æ®èç¹ï¼è·åå
¥å£è¿çº¿ |
| | | * @param source |
| | | * @return |
| | | */ |
| | | public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) { |
| | | List<SequenceFlow> 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<SequenceFlow> getElementOutgoingFlows(FlowElement source) { |
| | | List<SequenceFlow> 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<FlowElement> getAllElements(Collection<FlowElement> flowElements, Collection<FlowElement> 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<UserTask> iteratorFindParentUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> 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<SequenceFlow> 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<UserTask> 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<UserTask> iteratorFindChildUserTasks(FlowElement source, List<String> runTaskKeyList, Set<String> hasSequenceFlow, List<UserTask> userTaskList) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | userTaskList = iteratorFindChildUserTasks(source.getSubProcess(), runTaskKeyList, hasSequenceFlow, userTaskList); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> 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<UserTask> 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<UserTask> findChildProcessUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> 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<UserTask> 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<String> iteratorFindDirtyRoads(FlowElement source, List<String> passRoads, Set<String> hasSequenceFlow, List<String> targets, Set<String> 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<SequenceFlow> 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<String> findChildProcessAllDirtyRoad(FlowElement source, Set<String> hasSequenceFlow, Set<String> dirtyRoads) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> 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<String> hasSequenceFlow, List<String> targets, Boolean inChildProcess) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | inChildProcess = inChildProcess == null ? false : inChildProcess; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> 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<String> hasSequenceFlow, Boolean isSequential) { |
| | | isSequential = isSequential == null ? true : isSequential; |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | isSequential = iteratorCheckSequentialReferTarget(source.getSubProcess(), targetKsy, hasSequenceFlow, isSequential); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // å¦æç®æ èç¹å·²è¢«å¤æä¸ºå¹¶è¡ï¼åé¢é½ä¸éè¦æ§è¡ï¼ç´æ¥è¿å |
| | | if (isSequential == false) { |
| | | 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<List<UserTask>> findRoad(FlowElement source, List<UserTask> passRoads, Set<String> hasSequenceFlow, List<List<UserTask>> 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<SequenceFlow> 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<String> historicTaskInstanceClean(Collection<FlowElement> allElements, List<HistoricTaskInstance> historicTaskInstanceList) { |
| | | // ä¼ç¾èç¹æ¶é |
| | | List<String> 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<HistoricTaskInstance> stack = new Stack<>(); |
| | | historicTaskInstanceList.forEach(item -> stack.push(item)); |
| | | // æ¸
æ´åçåå²ä»»å¡å®ä¾ |
| | | List<String> lastHistoricTaskInstanceList = new ArrayList<>(); |
| | | // ç½å
³åå¨å¯è½åªèµ°äºé¨å忝æ
åµï¼ä¸è¿åå¨è·³è½¬åºå¼æ°æ®ä»¥åå
¶ä»åæ¯æ°æ®çå¹²æ°ï¼å æ¤éè¦å¯¹åå²èç¹æ°æ®è¿è¡æ¸
æ´ |
| | | // 临æ¶ç¨æ·ä»»å¡ key |
| | | StringBuilder userTaskKey = null; |
| | | // 临æ¶è¢«å æçä»»å¡ keyï¼åå¨å¹¶è¡æ
åµ |
| | | List<String> deleteKeyList = new ArrayList<>(); |
| | | // 临æ¶èæ°æ®çº¿è·¯ |
| | | List<Set<String>> 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<String> oldDirtyDataLine : dirtyDataLineList) { |
| | | if (oldDirtyDataLine.contains(stack.peek().getTaskDefinitionKey())) { |
| | | isDirtyData[0] = true; |
| | | } |
| | | } |
| | | // å é¤åå ä¸ä¸ºç©ºï¼è¯´æä»è¿æ¡æ°æ®å¼å§åè·³æè
åéç |
| | | // MI_ENDï¼ä¼ç¾å®æåï¼å
¶ä»æªç¾å°èç¹çå é¤åå ï¼ä¸å¨å¤çèå´å
|
| | | if (stack.peek().getDeleteReason() != null && !stack.peek().getDeleteReason().equals("MI_END")) { |
| | | // å¯ä»¥ç解为èçº¿è·¯èµ·ç¹ |
| | | String dirtyPoint = ""; |
| | | if (stack.peek().getDeleteReason().indexOf("Change activity to ") >= 0) { |
| | | dirtyPoint = stack.peek().getDeleteReason().replace("Change activity to ", ""); |
| | | } |
| | | // ä¼ç¾åéå é¤åå æç¹ä¸å |
| | | if (stack.peek().getDeleteReason().indexOf("Change parent activity to ") >= 0) { |
| | | 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<String> 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; |
| | | } |
| | | |
| | | /** |
| | | * æ·±æéå½è·åæµç¨æªéè¿çèç¹ |
| | | * @param bpmnModel æµç¨æ¨¡å |
| | | * @param unfinishedTaskSet æªç»æçä»»å¡èç¹ |
| | | * @param finishedSequenceFlowSet å·²ç»å®æçè¿çº¿ |
| | | * @param finishedTaskSet 已宿çä»»å¡èç¹ |
| | | * @return |
| | | */ |
| | | public static Set<String> dfsFindRejects(BpmnModel bpmnModel, Set<String> unfinishedTaskSet, Set<String> finishedSequenceFlowSet, Set<String> finishedTaskSet) { |
| | | if (ObjectUtil.isNull(bpmnModel)) { |
| | | throw new ServiceException("æµç¨æ¨¡åä¸åå¨"); |
| | | } |
| | | Collection<FlowElement> allElements = getAllElements(bpmnModel.getMainProcess().getFlowElements(), null); |
| | | Set<String> rejectedSet = new HashSet<>(); |
| | | for (FlowElement flowElement : allElements) { |
| | | // ç¨æ·èç¹ä¸æªç»æå
ç´ |
| | | if (flowElement instanceof UserTask && unfinishedTaskSet.contains(flowElement.getId())) { |
| | | List<String> hasSequenceFlow = iteratorFindFinishes(flowElement, null); |
| | | List<String> rejects = iteratorFindRejects(flowElement, finishedSequenceFlowSet, finishedTaskSet, hasSequenceFlow, null); |
| | | rejectedSet.addAll(rejects); |
| | | } |
| | | } |
| | | return rejectedSet; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£è·åç¶çº§èç¹å表ï¼ååæ¾ |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿çIDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @return |
| | | */ |
| | | public static List<String> iteratorFindFinishes(FlowElement source, List<String> hasSequenceFlow) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new ArrayList<>() : hasSequenceFlow; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | FlowElement finishedElement = sequenceFlow.getSourceFlowElement(); |
| | | // ç±»åä¸ºåæµç¨ï¼åæ·»å åæµç¨å¼å§èç¹åºå£å¤ç¸è¿çèç¹ |
| | | if (finishedElement instanceof SubProcess) { |
| | | FlowElement firstElement = (StartEvent) ((SubProcess) finishedElement).getFlowElements().toArray()[0]; |
| | | // è·ååæµç¨çè¿çº¿ |
| | | hasSequenceFlow.addAll(iteratorFindFinishes(firstElement, null)); |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | hasSequenceFlow = iteratorFindFinishes(finishedElement, hasSequenceFlow); |
| | | } |
| | | } |
| | | return hasSequenceFlow; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ£å¨è¿è¡çä»»å¡èç¹ï¼è¿ä»£è·åå级任å¡èç¹å表ï¼ååæ¾ |
| | | * @param source èµ·å§èç¹ |
| | | * @param finishedSequenceFlowSet å·²ç»å®æçè¿çº¿ |
| | | * @param finishedTaskSet å·²ç»å®æçä»»å¡èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param rejectedList æªéè¿çå
ç´ |
| | | * @return |
| | | */ |
| | | public static List<String> iteratorFindRejects(FlowElement source, Set<String> finishedSequenceFlowSet, Set<String> finishedTaskSet |
| | | , List<String> hasSequenceFlow, List<String> rejectedList) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new ArrayList<>() : hasSequenceFlow; |
| | | rejectedList = rejectedList == null ? new ArrayList<>() : rejectedList; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | FlowElement targetElement = sequenceFlow.getTargetFlowElement(); |
| | | // æ·»å æªå®æçèç¹ |
| | | if (finishedTaskSet.contains(targetElement.getId())) { |
| | | rejectedList.add(targetElement.getId()); |
| | | } |
| | | // æ·»å æªå®æçè¿çº¿ |
| | | if (finishedSequenceFlowSet.contains(sequenceFlow.getId())) { |
| | | rejectedList.add(sequenceFlow.getId()); |
| | | } |
| | | // 妿èç¹ä¸ºåæµç¨èç¹æ
åµï¼åä»èç¹ä¸ç第ä¸ä¸ªèç¹å¼å§è·å |
| | | if (targetElement instanceof SubProcess) { |
| | | FlowElement firstElement = (FlowElement) (((SubProcess) targetElement).getFlowElements().toArray()[0]); |
| | | List<String> childList = iteratorFindRejects(firstElement, finishedSequenceFlowSet, finishedTaskSet, hasSequenceFlow, null); |
| | | // 妿æ¾å°èç¹ï¼å说æè¯¥çº¿è·¯æ¾å°èç¹ï¼ä¸ç»§ç»å䏿¾ï¼åä¹ç»§ç» |
| | | if (childList != null && childList.size() > 0) { |
| | | rejectedList.addAll(childList); |
| | | continue; |
| | | } |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | rejectedList = iteratorFindRejects(targetElement, finishedSequenceFlowSet, finishedTaskSet, hasSequenceFlow, rejectedList); |
| | | } |
| | | } |
| | | return rejectedList; |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.listener; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import org.ruoyi.flowable.common.constant.ProcessConstants; |
| | | |
| | | import org.ruoyi.flowable.common.enums.ProcessStatus; |
| | | import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; |
| | | import org.flowable.engine.RuntimeService; |
| | | import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * Flowable å
¨å±çå¬å¨ |
| | | * |
| | | * @author konbai |
| | | * @since 2023/3/8 22:45 |
| | | */ |
| | | @Component |
| | | public class GlobalEventListener extends AbstractFlowableEngineEventListener { |
| | | |
| | | @Autowired |
| | | private RuntimeService runtimeService; |
| | | |
| | | /** |
| | | * æµç¨ç»æçå¬å¨ |
| | | */ |
| | | @Override |
| | | protected void processCompleted(FlowableEngineEntityEvent event) { |
| | | String processInstanceId = event.getProcessInstanceId(); |
| | | Object variable = runtimeService.getVariable(processInstanceId, ProcessConstants.PROCESS_STATUS_KEY); |
| | | ProcessStatus status = ProcessStatus.getProcessStatus(Convert.toStr(variable)); |
| | | if (ObjectUtil.isNotNull(status) && ProcessStatus.RUNNING == status) { |
| | | runtimeService.setVariable(processInstanceId, ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.COMPLETED.getStatus()); |
| | | } |
| | | super.processCompleted(event); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.listener; |
| | | |
| | | import org.flowable.engine.delegate.TaskListener; |
| | | import org.flowable.task.service.delegate.DelegateTask; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * ç¨æ·ä»»å¡çå¬å¨ |
| | | * |
| | | * @author KonBAI |
| | | * @since 2023/5/13 |
| | | */ |
| | | @Component(value = "userTaskListener") |
| | | public class UserTaskListener implements TaskListener { |
| | | |
| | | /** |
| | | * 注å
¥å段ï¼åç§°ä¸æµç¨è®¾è®¡æ¶å段åç§°ä¸è´ï¼ |
| | | */ |
| | | // private FixedValue field; |
| | | |
| | | @Override |
| | | public void notify(DelegateTask delegateTask) { |
| | | //TODO å®ç°ä½ çä»»å¡çå¬å¨é»è¾ |
| | | System.out.println("æ§è¡ä»»å¡çå¬å¨..."); |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.SimpleCache; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.ruoyi.common.core.utils.StreamUtils; |
| | | import org.springframework.cglib.beans.BeanCopier; |
| | | import org.springframework.cglib.beans.BeanMap; |
| | | import org.springframework.cglib.core.Converter; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * beanæ·±æ·è´å·¥å
·(åºäº cglib æ§è½ä¼å¼) |
| | | * <p> |
| | | * éç¹ cglib 䏿¯æ æ·è´å°é¾å¼å¯¹è±¡ |
| | | * ä¾å¦: æºå¯¹è±¡ æ·è´å° ç®æ (é¾å¼å¯¹è±¡) |
| | | * 请åºå好`æµ
æ·è´`å`æ·±æ·è´`ååä½¿ç¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class BeanCopyUtils { |
| | | |
| | | /** |
| | | * å对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, Class<V> desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | final V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | return copy(source, target); |
| | | } |
| | | |
| | | /** |
| | | * å对象åºäºå¯¹è±¡å建æ·è´ |
| | | * |
| | | * @param source æ°æ®æ¥æºå®ä½ |
| | | * @param desc 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V copy(T source, V desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(desc)) { |
| | | return null; |
| | | } |
| | | BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(source.getClass(), desc.getClass(), null); |
| | | beanCopier.copy(source, desc, null); |
| | | return desc; |
| | | } |
| | | |
| | | /** |
| | | * å表对象åºäºclasså建æ·è´ |
| | | * |
| | | * @param sourceList æ°æ®æ¥æºå®ä½å表 |
| | | * @param desc æè¿°å¯¹è±¡ 转æ¢åç对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> List<V> copyList(List<T> sourceList, Class<V> desc) { |
| | | if (ObjectUtil.isNull(sourceList)) { |
| | | return null; |
| | | } |
| | | if (CollUtil.isEmpty(sourceList)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return StreamUtils.toList(sourceList, source -> { |
| | | V target = ReflectUtil.newInstanceIfPossible(desc); |
| | | copy(source, target); |
| | | return target; |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * beanæ·è´å°map |
| | | * |
| | | * @param bean æ°æ®æ¥æºå®ä½ |
| | | * @return map对象 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> Map<String, Object> copyToMap(T bean) { |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | return BeanMap.create(bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param beanClass beanç±» |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, Class<T> beanClass) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(beanClass)) { |
| | | return null; |
| | | } |
| | | T bean = ReflectUtil.newInstanceIfPossible(beanClass); |
| | | return mapToBean(map, bean); |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°bean |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param bean bean对象 |
| | | * @return bean对象 |
| | | */ |
| | | public static <T> T mapToBean(Map<String, Object> map, T bean) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(bean)) { |
| | | return null; |
| | | } |
| | | BeanMap.create(bean).putAll(map); |
| | | return bean; |
| | | } |
| | | |
| | | /** |
| | | * mapæ·è´å°map |
| | | * |
| | | * @param map æ°æ®æ¥æº |
| | | * @param clazz è¿åç对象类å |
| | | * @return map对象 |
| | | */ |
| | | public static <T, V> Map<String, V> mapToMap(Map<String, T> map, Class<V> clazz) { |
| | | if (MapUtil.isEmpty(map)) { |
| | | return null; |
| | | } |
| | | if (ObjectUtil.isNull(clazz)) { |
| | | return null; |
| | | } |
| | | Map<String, V> copyMap = new LinkedHashMap<>(map.size()); |
| | | map.forEach((k, v) -> copyMap.put(k, copy(v, clazz))); |
| | | return copyMap; |
| | | } |
| | | |
| | | /** |
| | | * BeanCopier屿§ç¼å<br> |
| | | * ç¼åç¨äºé²æ¢å¤æ¬¡åå°é æçæ§è½é®é¢ |
| | | * |
| | | * @author Looly |
| | | * @since 5.4.1 |
| | | */ |
| | | public enum BeanCopierCache { |
| | | /** |
| | | * BeanCopier屿§ç¼ååä¾ |
| | | */ |
| | | INSTANCE; |
| | | |
| | | private final SimpleCache<String, BeanCopier> cache = new SimpleCache<>(); |
| | | |
| | | /** |
| | | * è·å¾ç±»ä¸è½¬æ¢å¨çæçkeyå¨{@link BeanCopier}çMapä¸å¯¹åºçå
ç´ |
| | | * |
| | | * @param srcClass æºBeançç±» |
| | | * @param targetClass ç®æ Beançç±» |
| | | * @param converter 转æ¢å¨ |
| | | * @return Mapä¸å¯¹åºçBeanCopier |
| | | */ |
| | | public BeanCopier get(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final String key = genKey(srcClass, targetClass, converter); |
| | | return cache.get(key, () -> BeanCopier.create(srcClass, targetClass, converter != null)); |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ç±»ä¸è½¬æ¢å¨çæçkey |
| | | * |
| | | * @param srcClass æºBeançç±» |
| | | * @param targetClass ç®æ Beançç±» |
| | | * @param converter 转æ¢å¨ |
| | | * @return 屿§ååMapæ å°çkey |
| | | */ |
| | | private String genKey(Class<?> srcClass, Class<?> targetClass, Converter converter) { |
| | | final StringBuilder key = StrUtil.builder() |
| | | .append(srcClass.getName()).append('#').append(targetClass.getName()); |
| | | if (null != converter) { |
| | | key.append('#').append(converter.getClass().getName()); |
| | | } |
| | | return key.toString(); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.exc.MismatchedInputException; |
| | | import org.ruoyi.common.core.utils.SpringUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * JSON å·¥å
·ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class JsonUtils { |
| | | |
| | | private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class); |
| | | |
| | | public static ObjectMapper getObjectMapper() { |
| | | return OBJECT_MAPPER; |
| | | } |
| | | |
| | | public static String toJsonString(Object object) { |
| | | if (ObjectUtil.isNull(object)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.writeValueAsString(object); |
| | | } catch (JsonProcessingException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, clazz); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(byte[] bytes, Class<T> clazz) { |
| | | if (ArrayUtil.isEmpty(bytes)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(bytes, clazz); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> T parseObject(String text, TypeReference<T> typeReference) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, typeReference); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static Dict parseMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class)); |
| | | } catch (MismatchedInputException e) { |
| | | // ç±»åä¸å¹é
说æä¸æ¯json |
| | | return null; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static List<Dict> parseArrayMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class)); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> List<T> parseArray(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | try { |
| | | return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz)); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.common.engine.impl.util.io.StringStreamSource; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/26 19:04 |
| | | */ |
| | | public class ModelUtils { |
| | | |
| | | private static final BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter(); |
| | | |
| | | /** |
| | | * xml转bpmnModel对象 |
| | | * |
| | | * @param xml xml |
| | | * @return bpmnModel对象 |
| | | */ |
| | | public static BpmnModel getBpmnModel(String xml) { |
| | | return bpmnXMLConverter.convertToBpmnModel(new StringStreamSource(xml), false, false); |
| | | } |
| | | |
| | | /** |
| | | * bpmnModel转xmlå符串 |
| | | * |
| | | * @deprecated åå¨ä¼ä¸¢å¤± bpmn è¿çº¿é®é¢ |
| | | * @param bpmnModel bpmnModel对象 |
| | | * @return xmlå符串 |
| | | */ |
| | | @Deprecated |
| | | public static String getBpmnXmlStr(BpmnModel bpmnModel) { |
| | | return StrUtil.utf8Str(getBpmnXml(bpmnModel)); |
| | | } |
| | | |
| | | /** |
| | | * bpmnModel转xml对象 |
| | | * |
| | | * @deprecated åå¨ä¸¢å¤± bpmn è¿çº¿é®é¢ |
| | | * @param bpmnModel bpmnModel对象 |
| | | * @return xml |
| | | */ |
| | | @Deprecated |
| | | public static byte[] getBpmnXml(BpmnModel bpmnModel) { |
| | | return bpmnXMLConverter.convertToXML(bpmnModel); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®èç¹ï¼è·åå
¥å£è¿çº¿ |
| | | * |
| | | * @param source èµ·å§èç¹ |
| | | * @return å
¥å£è¿çº¿å表 |
| | | */ |
| | | public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) { |
| | | List<SequenceFlow> sequenceFlows = new ArrayList<>(); |
| | | if (source instanceof FlowNode) { |
| | | sequenceFlows = ((FlowNode) source).getIncomingFlows(); |
| | | } |
| | | return sequenceFlows; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®èç¹ï¼è·ååºå£è¿çº¿ |
| | | * |
| | | * @param source èµ·å§èç¹ |
| | | * @return åºå£è¿çº¿å表 |
| | | */ |
| | | public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) { |
| | | List<SequenceFlow> sequenceFlows = new ArrayList<>(); |
| | | if (source instanceof FlowNode) { |
| | | sequenceFlows = ((FlowNode) source).getOutgoingFlows(); |
| | | } |
| | | return sequenceFlows; |
| | | } |
| | | |
| | | /** |
| | | * è·åå¼å§èç¹ |
| | | * |
| | | * @param model bpmnModel对象 |
| | | * @return å¼å§èç¹ï¼æªæ¾å°å¼å§èç¹ï¼è¿ånullï¼ |
| | | */ |
| | | public static StartEvent getStartEvent(BpmnModel model) { |
| | | Process process = model.getMainProcess(); |
| | | FlowElement startElement = process.getInitialFlowElement(); |
| | | if (startElement instanceof StartEvent) { |
| | | return (StartEvent) startElement; |
| | | } |
| | | return getStartEvent(process.getFlowElements()); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¼å§èç¹ |
| | | * |
| | | * @param flowElements æµç¨å
ç´ éå |
| | | * @return å¼å§èç¹ï¼æªæ¾å°å¼å§èç¹ï¼è¿ånullï¼ |
| | | */ |
| | | public static StartEvent getStartEvent(Collection<FlowElement> flowElements) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof StartEvent) { |
| | | return (StartEvent) flowElement; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åç»æèç¹ |
| | | * |
| | | * @param model bpmnModel对象 |
| | | * @return ç»æèç¹ï¼æªæ¾å°å¼å§èç¹ï¼è¿ånullï¼ |
| | | */ |
| | | public static EndEvent getEndEvent(BpmnModel model) { |
| | | Process process = model.getMainProcess(); |
| | | return getEndEvent(process.getFlowElements()); |
| | | } |
| | | |
| | | /** |
| | | * è·åç»æèç¹ |
| | | * |
| | | * @param flowElements æµç¨å
ç´ éå |
| | | * @return ç»æèç¹ï¼æªæ¾å°å¼å§èç¹ï¼è¿ånullï¼ |
| | | */ |
| | | public static EndEvent getEndEvent(Collection<FlowElement> flowElements) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof EndEvent) { |
| | | return (EndEvent) flowElement; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static UserTask getUserTaskByKey(BpmnModel model, String taskKey) { |
| | | Process process = model.getMainProcess(); |
| | | FlowElement flowElement = process.getFlowElement(taskKey); |
| | | if (flowElement instanceof UserTask) { |
| | | return (UserTask) flowElement; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨å
ç´ ä¿¡æ¯ |
| | | * |
| | | * @param model bpmnModel对象 |
| | | * @param flowElementId å
ç´ ID |
| | | * @return å
ç´ ä¿¡æ¯ |
| | | */ |
| | | public static FlowElement getFlowElementById(BpmnModel model, String flowElementId) { |
| | | Process process = model.getMainProcess(); |
| | | return process.getFlowElement(flowElementId); |
| | | } |
| | | |
| | | /** |
| | | * è·åå
ç´ è¡¨åKeyï¼éå¼å§èç¹åç¨æ·èç¹å¯ç¨ï¼ |
| | | * |
| | | * @param flowElement å
ç´ |
| | | * @return 表åKey |
| | | */ |
| | | public static String getFormKey(FlowElement flowElement) { |
| | | if (flowElement != null) { |
| | | if (flowElement instanceof StartEvent) { |
| | | return ((StartEvent) flowElement).getFormKey(); |
| | | } else if (flowElement instanceof UserTask) { |
| | | return ((UserTask) flowElement).getFormKey(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åå¼å§èç¹å±æ§å¼ |
| | | * @param model bpmnModel对象 |
| | | * @param name 屿§å |
| | | * @return 屿§å¼ |
| | | */ |
| | | public static String getStartEventAttributeValue(BpmnModel model, String name) { |
| | | StartEvent startEvent = getStartEvent(model); |
| | | return getElementAttributeValue(startEvent, name); |
| | | } |
| | | |
| | | /** |
| | | * è·åç»æèç¹å±æ§å¼ |
| | | * @param model bpmnModel对象 |
| | | * @param name 屿§å |
| | | * @return 屿§å¼ |
| | | */ |
| | | public static String getEndEventAttributeValue(BpmnModel model, String name) { |
| | | EndEvent endEvent = getEndEvent(model); |
| | | return getElementAttributeValue(endEvent, name); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·ä»»å¡èç¹å±æ§å¼ |
| | | * @param model bpmnModel对象 |
| | | * @param taskKey ä»»å¡Key |
| | | * @param name 屿§å |
| | | * @return 屿§å¼ |
| | | */ |
| | | public static String getUserTaskAttributeValue(BpmnModel model, String taskKey, String name) { |
| | | UserTask userTask = getUserTaskByKey(model, taskKey); |
| | | return getElementAttributeValue(userTask, name); |
| | | } |
| | | |
| | | /** |
| | | * è·åå
ç´ å±æ§å¼ |
| | | * @param baseElement æµç¨å
ç´ |
| | | * @param name 屿§å |
| | | * @return 屿§å¼ |
| | | */ |
| | | public static String getElementAttributeValue(BaseElement baseElement, String name) { |
| | | if (baseElement != null) { |
| | | List<ExtensionAttribute> attributes = baseElement.getAttributes().get(name); |
| | | if (attributes != null && !attributes.isEmpty()) { |
| | | attributes.iterator().next().getValue(); |
| | | Iterator<ExtensionAttribute> attrIterator = attributes.iterator(); |
| | | if(attrIterator.hasNext()) { |
| | | ExtensionAttribute attribute = attrIterator.next(); |
| | | return attribute.getValue(); |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static boolean isMultiInstance(BpmnModel model, String taskKey) { |
| | | UserTask userTask = getUserTaskByKey(model, taskKey); |
| | | if (ObjectUtil.isNotNull(userTask)) { |
| | | return userTask.hasMultiInstanceLoopCharacteristics(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * è·åææç¨æ·ä»»å¡èç¹ |
| | | * |
| | | * @param model bpmnModel对象 |
| | | * @return ç¨æ·ä»»å¡èç¹å表 |
| | | */ |
| | | public static Collection<UserTask> getAllUserTaskEvent(BpmnModel model) { |
| | | Process process = model.getMainProcess(); |
| | | Collection<FlowElement> flowElements = process.getFlowElements(); |
| | | return getAllUserTaskEvent(flowElements, null); |
| | | } |
| | | |
| | | /** |
| | | * è·åææç¨æ·ä»»å¡èç¹ |
| | | * @param flowElements æµç¨å
ç´ éå |
| | | * @param allElements æææµç¨å
ç´ éå |
| | | * @return ç¨æ·ä»»å¡èç¹å表 |
| | | */ |
| | | public static Collection<UserTask> getAllUserTaskEvent(Collection<FlowElement> flowElements, Collection<UserTask> allElements) { |
| | | allElements = allElements == null ? new ArrayList<>() : allElements; |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof UserTask) { |
| | | allElements.add((UserTask) flowElement); |
| | | } |
| | | if (flowElement instanceof SubProcess) { |
| | | // ç»§ç»æ·±å
¥åæµç¨ï¼è¿ä¸æ¥è·ååæµç¨ |
| | | allElements = getAllUserTaskEvent(((SubProcess) flowElement).getFlowElements(), allElements); |
| | | } |
| | | } |
| | | return allElements; |
| | | } |
| | | |
| | | /** |
| | | * æ¥æ¾èµ·å§èç¹ä¸ä¸ä¸ªç¨æ·ä»»å¡å表å表 |
| | | * @param source èµ·å§èç¹ |
| | | * @return ç»æ |
| | | */ |
| | | public static List<UserTask> findNextUserTasks(FlowElement source) { |
| | | return findNextUserTasks(source, null, null); |
| | | } |
| | | |
| | | /** |
| | | * æ¥æ¾èµ·å§èç¹ä¸ä¸ä¸ªç¨æ·ä»»å¡å表å表 |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param userTaskList ç¨æ·ä»»å¡å表 |
| | | * @return ç»æ |
| | | */ |
| | | public static List<UserTask> findNextUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) { |
| | | hasSequenceFlow = Optional.ofNullable(hasSequenceFlow).orElse(new HashSet<>()); |
| | | userTaskList = Optional.ofNullable(userTaskList).orElse(new ArrayList<>()); |
| | | // è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | if (!sequenceFlows.isEmpty()) { |
| | | for (SequenceFlow sequenceFlow : sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement(); |
| | | if (targetFlowElement instanceof UserTask) { |
| | | // è¥èç¹ä¸ºç¨æ·ä»»å¡ï¼å å
¥å°ç»æåè¡¨ä¸ |
| | | userTaskList.add((UserTask) targetFlowElement); |
| | | } else { |
| | | // è¥èç¹éç¨æ·ä»»å¡ï¼ç»§ç»é彿¥æ¾ä¸ä¸ä¸ªèç¹ |
| | | findNextUserTasks(targetFlowElement, hasSequenceFlow, userTaskList); |
| | | } |
| | | } |
| | | } |
| | | return userTaskList; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£ä»åååæ«æï¼å¤æç®æ èç¹ç¸å¯¹äºå½åèç¹æ¯å¦æ¯ä¸²è¡ |
| | | * ä¸åå¨ç´æ¥åéå°åæµç¨ä¸çæ
åµï¼ä½åå¨ä»åæµç¨åºå»å°ç¶æµç¨æ
åµ |
| | | * @param source èµ·å§èç¹ |
| | | * @param target ç®æ èç¹ |
| | | * @param visitedElements å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) { |
| | | visitedElements = visitedElements == null ? new HashSet<>() : visitedElements; |
| | | if (source instanceof StartEvent && isInEventSubprocess(source)) { |
| | | return false; |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | if (sequenceFlows != null && sequenceFlows.size() > 0) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (visitedElements.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | visitedElements.add(sequenceFlow.getId()); |
| | | FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement(); |
| | | // è¿æ¡çº¿è·¯åå¨ç®æ èç¹ï¼è¿æ¡çº¿è·¯å®æï¼è¿å
¥ä¸ä¸ªçº¿è·¯ |
| | | if (target.getId().equals(sourceFlowElement.getId())) { |
| | | continue; |
| | | } |
| | | // å¦æç®æ èç¹ä¸ºå¹¶è¡ç½å
³ï¼åä¸ç»§ç» |
| | | if (sourceFlowElement instanceof ParallelGateway) { |
| | | return false; |
| | | } |
| | | // å¦å就继ç»è¿ä»£ |
| | | boolean isSequential = isSequentialReachable(sourceFlowElement, target, visitedElements); |
| | | if (!isSequential) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | protected static boolean isInEventSubprocess(FlowElement flowElement) { |
| | | FlowElementsContainer flowElementsContainer = flowElement.getParentContainer(); |
| | | while (flowElementsContainer != null) { |
| | | if (flowElementsContainer instanceof EventSubProcess) { |
| | | return true; |
| | | } |
| | | |
| | | if (flowElementsContainer instanceof FlowElement) { |
| | | flowElementsContainer = ((FlowElement) flowElementsContainer).getParentContainer(); |
| | | } else { |
| | | flowElementsContainer = null; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import org.ruoyi.flowable.core.FormConf; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åå·¥å
·ç±» |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/8/7 17:09 |
| | | */ |
| | | public class ProcessFormUtils { |
| | | |
| | | private static final String CONFIG = "__config__"; |
| | | private static final String MODEL = "__vModel__"; |
| | | |
| | | /** |
| | | * å¡«å
表å项å
容 |
| | | * |
| | | * @param formConf 表åé
ç½®ä¿¡æ¯ |
| | | * @param data 表åå
容 |
| | | */ |
| | | public static void fillFormData(FormConf formConf, Map<String, Object> data) { |
| | | for (Map<String, Object> field : formConf.getFields()) { |
| | | recursiveFillField(field, data); |
| | | } |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private static void recursiveFillField(final Map<String, Object> field, final Map<String, Object> data) { |
| | | if (!field.containsKey(CONFIG)) { |
| | | return; |
| | | } |
| | | Map<String, Object> configMap = (Map<String, Object>) field.get(CONFIG); |
| | | if (configMap.containsKey("children")) { |
| | | List<Map<String, Object>> childrens = (List<Map<String, Object>>) configMap.get("children"); |
| | | for (Map<String, Object> children : childrens) { |
| | | recursiveFillField(children, data); |
| | | } |
| | | } |
| | | String modelKey = Convert.toStr(field.get(MODEL)); |
| | | Object value = data.get(modelKey); |
| | | if (value != null) { |
| | | configMap.put("defaultValue", value); |
| | | } |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import org.ruoyi.common.core.utils.DateUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.flowable.common.engine.api.query.Query; |
| | | import org.flowable.common.engine.impl.db.SuspensionState; |
| | | import org.flowable.engine.history.HistoricProcessInstanceQuery; |
| | | import org.flowable.engine.repository.ProcessDefinitionQuery; |
| | | import org.flowable.task.api.TaskQuery; |
| | | import org.flowable.task.api.history.HistoricTaskInstanceQuery; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨å·¥å
·ç±» |
| | | * |
| | | * @author konbai |
| | | * @since 2022/12/11 03:35 |
| | | */ |
| | | public class ProcessUtils { |
| | | |
| | | public static void buildProcessSearch(Query<?, ?> query, ProcessQuery process) { |
| | | if (query instanceof ProcessDefinitionQuery) { |
| | | buildProcessDefinitionSearch((ProcessDefinitionQuery) query, process); |
| | | } else if (query instanceof TaskQuery) { |
| | | buildTaskSearch((TaskQuery) query, process); |
| | | } else if (query instanceof HistoricTaskInstanceQuery) { |
| | | buildHistoricTaskInstanceSearch((HistoricTaskInstanceQuery) query, process); |
| | | } else if (query instanceof HistoricProcessInstanceQuery) { |
| | | buildHistoricProcessInstanceSearch((HistoricProcessInstanceQuery) query, process); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæµç¨å®ä¹æç´¢ |
| | | */ |
| | | public static void buildProcessDefinitionSearch(ProcessDefinitionQuery query, ProcessQuery process) { |
| | | // æµç¨æ è¯ |
| | | if (StringUtils.isNotBlank(process.getProcessKey())) { |
| | | query.processDefinitionKeyLike("%" + process.getProcessKey() + "%"); |
| | | } |
| | | // æµç¨åç§° |
| | | if (StringUtils.isNotBlank(process.getProcessName())) { |
| | | query.processDefinitionNameLike("%" + process.getProcessName() + "%"); |
| | | } |
| | | // æµç¨åç±» |
| | | if (StringUtils.isNotBlank(process.getCategory())) { |
| | | query.processDefinitionCategory(process.getCategory()); |
| | | } |
| | | // æµç¨ç¶æ |
| | | if (StringUtils.isNotBlank(process.getState())) { |
| | | if (SuspensionState.ACTIVE.toString().equals(process.getState())) { |
| | | query.active(); |
| | | } else if (SuspensionState.SUSPENDED.toString().equals(process.getState())) { |
| | | query.suspended(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå»ºä»»å¡æç´¢ |
| | | */ |
| | | public static void buildTaskSearch(TaskQuery query, ProcessQuery process) { |
| | | Map<String, Object> params = process.getParams(); |
| | | if (StringUtils.isNotBlank(process.getProcessKey())) { |
| | | query.processDefinitionKeyLike("%" + process.getProcessKey() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(process.getProcessName())) { |
| | | query.processDefinitionNameLike("%" + process.getProcessName() + "%"); |
| | | } |
| | | if (params.get("beginTime") != null && params.get("endTime") != null) { |
| | | query.taskCreatedAfter(DateUtils.parseDate(params.get("beginTime"))); |
| | | query.taskCreatedBefore(DateUtils.parseDate(params.get("endTime"))); |
| | | } |
| | | // æµç¨åç±» |
| | | if (StringUtils.isNotBlank(process.getCategory())) { |
| | | query.processCategoryIn(Collections.singleton(process.getCategory())); |
| | | } |
| | | } |
| | | |
| | | private static void buildHistoricTaskInstanceSearch(HistoricTaskInstanceQuery query, ProcessQuery process) { |
| | | Map<String, Object> params = process.getParams(); |
| | | if (StringUtils.isNotBlank(process.getProcessKey())) { |
| | | query.processDefinitionKeyLike("%" + process.getProcessKey() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(process.getProcessName())) { |
| | | query.processDefinitionNameLike("%" + process.getProcessName() + "%"); |
| | | } |
| | | if (params.get("beginTime") != null && params.get("endTime") != null) { |
| | | query.taskCompletedAfter(DateUtils.parseDate(params.get("beginTime"))); |
| | | query.taskCompletedBefore(DateUtils.parseDate(params.get("endTime"))); |
| | | } |
| | | // æµç¨åç±» |
| | | if (StringUtils.isNotBlank(process.getCategory())) { |
| | | query.processCategoryIn(Collections.singleton(process.getCategory())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå»ºå岿µç¨å®ä¾æç´¢ |
| | | */ |
| | | public static void buildHistoricProcessInstanceSearch(HistoricProcessInstanceQuery query, ProcessQuery process) { |
| | | Map<String, Object> params = process.getParams(); |
| | | // æµç¨æ è¯ |
| | | if (StringUtils.isNotBlank(process.getProcessKey())) { |
| | | query.processDefinitionKey(process.getProcessKey()); |
| | | } |
| | | // æµç¨åç§° |
| | | if (StringUtils.isNotBlank(process.getProcessName())) { |
| | | query.processDefinitionName(process.getProcessName()); |
| | | } |
| | | // æµç¨åç§° |
| | | if (StringUtils.isNotBlank(process.getCategory())) { |
| | | query.processDefinitionCategory(process.getCategory()); |
| | | } |
| | | if (params.get("beginTime") != null && params.get("endTime") != null) { |
| | | query.startedAfter(DateUtils.parseDate(params.get("beginTime"))); |
| | | query.startedBefore(DateUtils.parseDate(params.get("endTime"))); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.*; |
| | | import java.util.function.BiFunction; |
| | | import java.util.function.Function; |
| | | import java.util.function.Predicate; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * stream æµå·¥å
·ç±» |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class StreamUtils { |
| | | |
| | | /** |
| | | * å°collectionè¿æ»¤ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function è¿æ»¤æ¹æ³ |
| | | * @return è¿æ»¤åçlist |
| | | */ |
| | | public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection.stream().filter(function).collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæ¼æ¥ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function æ¼æ¥æ¹æ³ |
| | | * @return æ¼æ¥åçlist |
| | | */ |
| | | public static <E> String join(Collection<E> collection, Function<E, String> function) { |
| | | return join(collection, function, ","); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæ¼æ¥ |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function æ¼æ¥æ¹æ³ |
| | | * @param delimiter æ¼æ¥ç¬¦ |
| | | * @return æ¼æ¥åçlist |
| | | */ |
| | | public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | | return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter)); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæåº |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param comparing æåºæ¹æ³ |
| | | * @return æåºåçlist |
| | | */ |
| | | public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection.stream().sorted(comparing).collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为类åä¸åçmap<br> |
| | | * <B>{@code Collection<V> ----> Map<K,V>}</B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param key Vç±»å转å为Kç±»åçlambdaæ¹æ³ |
| | | * @param <V> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @return 转ååçmap |
| | | */ |
| | | public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l)); |
| | | } |
| | | |
| | | /** |
| | | * å°Collection转å为map(valueç±»åä¸collectionçæ³åä¸å)<br> |
| | | * <B>{@code Collection<E> -----> Map<K,V> }</B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param key Eç±»å转å为Kç±»åçlambdaæ¹æ³ |
| | | * @param value Eç±»å转å为Vç±»åçlambdaæ¹æ³ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @param <V> mapä¸çvalueç±»å |
| | | * @return 转ååçmap |
| | | */ |
| | | public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l)); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§è§å(æ¯å¦æç¸åçç级id)åç±»æmap<br> |
| | | * <B>{@code Collection<E> -------> Map<K,List<E>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key åç±»çè§å |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList())); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§ä¸¤ä¸ªè§å(æ¯å¦æç¸åç年级id,ç级id)åç±»æåå±map<br> |
| | | * <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key1 第ä¸ä¸ªåç±»çè§å |
| | | * @param key2 第äºä¸ªåç±»çè§å |
| | | * @param <E> éåå
ç´ ç±»å |
| | | * @param <K> 第ä¸ä¸ªmapä¸çkeyç±»å |
| | | * @param <U> 第äºä¸ªmapä¸çkeyç±»å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList()))); |
| | | } |
| | | |
| | | /** |
| | | * å°collectionæç
§ä¸¤ä¸ªè§å(æ¯å¦æç¸åç年级id,ç级id)åç±»æåå±map<br> |
| | | * <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B> |
| | | * |
| | | * @param collection éè¦åç±»çéå |
| | | * @param key1 第ä¸ä¸ªåç±»çè§å |
| | | * @param key2 第äºä¸ªåç±»çè§å |
| | | * @param <T> 第ä¸ä¸ªmapä¸çkeyç±»å |
| | | * @param <U> 第äºä¸ªmapä¸çkeyç±»å |
| | | * @param <E> collectionä¸çæ³å |
| | | * @return åç±»åçmap |
| | | */ |
| | | public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) { |
| | | if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) { |
| | | return MapUtil.newHashMap(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l))); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为Listéåï¼ä½æ¯ä¸¤è
çæ³åä¸å<br> |
| | | * <B>{@code Collection<E> ------> List<T> } </B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function collectionä¸çæ³å转å为listæ³åçlambdaè¡¨è¾¾å¼ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <T> Listä¸çæ³å |
| | | * @return 转ååçlist |
| | | */ |
| | | public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) { |
| | | if (CollUtil.isEmpty(collection)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .map(function) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * å°collection转å为Setéåï¼ä½æ¯ä¸¤è
çæ³åä¸å<br> |
| | | * <B>{@code Collection<E> ------> Set<T> } </B> |
| | | * |
| | | * @param collection éè¦è½¬åçéå |
| | | * @param function collectionä¸çæ³å转å为setæ³åçlambdaè¡¨è¾¾å¼ |
| | | * @param <E> collectionä¸çæ³å |
| | | * @param <T> Setä¸çæ³å |
| | | * @return 转ååçSet |
| | | */ |
| | | public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) { |
| | | if (CollUtil.isEmpty(collection) || function == null) { |
| | | return CollUtil.newHashSet(); |
| | | } |
| | | return collection |
| | | .stream() |
| | | .map(function) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * å并两个ç¸åkeyç±»åçmap |
| | | * |
| | | * @param map1 第ä¸ä¸ªéè¦åå¹¶ç map |
| | | * @param map2 第äºä¸ªéè¦åå¹¶ç map |
| | | * @param merge åå¹¶çlambdaï¼å°key value1 value2åå¹¶ææç»çç±»å,注ævalueå¯è½ä¸ºç©ºçæ
åµ |
| | | * @param <K> mapä¸çkeyç±»å |
| | | * @param <X> 第ä¸ä¸ª mapçvalueç±»å |
| | | * @param <Y> 第äºä¸ª mapçvalueç±»å |
| | | * @param <V> æç»mapçvalueç±»å |
| | | * @return åå¹¶åçmap |
| | | */ |
| | | public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) { |
| | | if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) { |
| | | return MapUtil.newHashMap(); |
| | | } else if (MapUtil.isEmpty(map1)) { |
| | | map1 = MapUtil.newHashMap(); |
| | | } else if (MapUtil.isEmpty(map2)) { |
| | | map2 = MapUtil.newHashMap(); |
| | | } |
| | | Set<K> key = new HashSet<>(); |
| | | key.addAll(map1.keySet()); |
| | | key.addAll(map2.keySet()); |
| | | Map<K, V> map = new HashMap<>(); |
| | | for (K t : key) { |
| | | X x = map1.get(t); |
| | | Y y = map2.get(t); |
| | | V z = merge.apply(x, y); |
| | | if (z != null) { |
| | | map.put(t, z); |
| | | } |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.utils; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import org.ruoyi.common.core.domain.model.LoginUser; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.flowable.common.constant.TaskConstants; |
| | | |
| | | import java.security.Security; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 工使µä»»å¡å·¥å
·ç±» |
| | | * |
| | | * @author konbai |
| | | * @createTime 2022/4/24 12:42 |
| | | */ |
| | | public class TaskUtils { |
| | | public static String getUserId() { |
| | | |
| | | LoginUser user = LoginHelper.getLoginUser(); |
| | | if (ObjectUtil.isNotNull(user)) { |
| | | return String.valueOf(user.getUserId()); |
| | | } |
| | | |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·ç»ä¿¡æ¯ |
| | | * |
| | | * @return candidateGroup |
| | | */ |
| | | public static List<String> getCandidateGroup() { |
| | | List<String> list = new ArrayList<>(); |
| | | LoginUser user = LoginHelper.getLoginUser(); |
| | | if (ObjectUtil.isNotNull(user)) { |
| | | if (ObjectUtil.isNotEmpty(user.getRoles())) { |
| | | user.getRoles().forEach(role -> list.add(TaskConstants.ROLE_GROUP_PREFIX + role.getRoleId() )); |
| | | } |
| | | if (ObjectUtil.isNotNull(user.getDeptId())) { |
| | | list.add(TaskConstants.DEPT_GROUP_PREFIX + user.getDeptId()); |
| | | } |
| | | } |
| | | |
| | | return list; |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.WfCategory; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCategoryVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfCategoryService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import org.ruoyi.common.excel.utils.ExcelUtil; |
| | | |
| | | /** |
| | | * æµç¨åç±»Controller |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/category") |
| | | public class WfCategoryController extends BaseController { |
| | | |
| | | private final IWfCategoryService categoryService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»å表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<WfCategoryVo> list(WfCategory category) { |
| | | List<WfCategoryVo> list = categoryService.queryList(category); |
| | | return TableDataInfo.build(list); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å
¨é¨çæµç¨åç±»å表 |
| | | */ |
| | | @GetMapping("/listAll") |
| | | public R<List<WfCategoryVo>> listAll(WfCategory category) { |
| | | return R.ok(categoryService.queryList(category)); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµç¨åç±»å表 |
| | | */ |
| | | @PostMapping("/export") |
| | | public void export(@Validated WfCategory category, HttpServletResponse response) { |
| | | List<WfCategoryVo> list = categoryService.queryList(category); |
| | | List<WfCategoryVo> util = MapstructUtils.convert(list,WfCategoryVo.class); |
| | | ExcelUtil.exportExcel(util, "æµç¨åç±»", WfCategoryVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨å类详ç»ä¿¡æ¯ |
| | | * @param categoryId åç±»ä¸»é® |
| | | */ |
| | | @GetMapping("/{categoryId}") |
| | | public R<WfCategoryVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") @PathVariable("categoryId") Long categoryId) { |
| | | return R.ok(categoryService.queryById(categoryId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨åç±» |
| | | */ |
| | | @PostMapping |
| | | public R add(@Validated @RequestBody WfCategory category) { |
| | | if (!categoryService.checkCategoryCodeUnique(category)) { |
| | | return R.fail("æ°å¢æµç¨åç±»'" + category.getCategoryName() + "'å¤±è´¥ï¼æµç¨ç¼ç å·²åå¨"); |
| | | } |
| | | return R.ok(categoryService.insertCategory(category)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨åç±» |
| | | */ |
| | | @PutMapping() |
| | | public R edit(@Validated @RequestBody WfCategory category) { |
| | | if (!categoryService.checkCategoryCodeUnique(category)) { |
| | | return R.fail("ä¿®æ¹æµç¨åç±»'" + category.getCategoryName() + "'å¤±è´¥ï¼æµç¨ç¼ç å·²åå¨"); |
| | | } |
| | | return toAjax(categoryService.updateCategory(category)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨åç±» |
| | | * @param categoryIds å类主é®ä¸² |
| | | */ |
| | | @DeleteMapping("/{categoryIds}") |
| | | public R remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") @PathVariable Long[] categoryIds) { |
| | | return toAjax(categoryService.deleteWithValidByIds(Arrays.asList(categoryIds), true)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.utils.JsonUtils; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDeployVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployFormService; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import java.util.Arrays; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æµç¨é¨ç½² |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/24 20:57 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/deploy") |
| | | public class WfDeployController extends BaseController { |
| | | |
| | | private final IWfDeployService deployService; |
| | | private final IWfDeployFormService deployFormService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨é¨ç½²å表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<WfDeployVo> list(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return deployService.queryPageList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨é¨ç½²çæ¬å表 |
| | | */ |
| | | @GetMapping("/publishList") |
| | | public TableDataInfo<WfDeployVo> publishList(@RequestParam String processKey, PageQuery pageQuery) { |
| | | return deployService.queryPublishList(processKey, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¿æ´»ææèµ·æµç¨ |
| | | * |
| | | * @param state ç¶æï¼active:æ¿æ´» suspended:æèµ·ï¼ |
| | | * @param definitionId æµç¨å®ä¹ID |
| | | */ |
| | | @PutMapping(value = "/changeState") |
| | | public R<Void> changeState(@RequestParam String state, @RequestParam String definitionId) { |
| | | deployService.updateState(definitionId, state); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 读åxmlæä»¶ |
| | | * @param definitionId æµç¨å®ä¹ID |
| | | * @return |
| | | */ |
| | | @GetMapping("/bpmnXml/{definitionId}") |
| | | public R<String> getBpmnXml(@PathVariable(value = "definitionId") String definitionId) { |
| | | return R.ok( deployService.queryBpmnXmlById(definitionId),null); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨æ¨¡å |
| | | * @param deployIds æµç¨é¨ç½²ids |
| | | */ |
| | | @DeleteMapping("/{deployIds}") |
| | | public R<String> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") @PathVariable String[] deployIds) { |
| | | deployService.deleteByIds(Arrays.asList(deployIds)); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨é¨ç½²å
³è表åä¿¡æ¯ |
| | | * |
| | | * @param deployId æµç¨é¨ç½²id |
| | | */ |
| | | @GetMapping("/form/{deployId}") |
| | | public R<?> start(@PathVariable(value = "deployId") String deployId) { |
| | | WfFormVo formVo = deployFormService.selectDeployFormByDeployId(deployId); |
| | | if (Objects.isNull(formVo)) { |
| | | return R.fail("请å
é
ç½®æµç¨è¡¨å"); |
| | | } |
| | | return R.ok(JsonUtils.parseObject(formVo.getContent(), Map.class)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.core.validate.QueryGroup; |
| | | import org.ruoyi.common.excel.utils.ExcelUtil; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfFormBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployFormService; |
| | | import org.ruoyi.flowable.workflow.service.IWfFormService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åController |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/form") |
| | | public class WfFormController extends BaseController { |
| | | |
| | | private final IWfFormService formService; |
| | | |
| | | private final IWfDeployFormService deployFormService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨åå表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<WfFormVo> list(@Validated(QueryGroup.class) WfFormBo bo, PageQuery pageQuery) { |
| | | return formService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµç¨è¡¨åå表 |
| | | */ |
| | | @PostMapping("/export") |
| | | public void export(@Validated WfFormBo bo, HttpServletResponse response) { |
| | | List<WfFormVo> list = formService.queryList(bo); |
| | | List<WfFormVo> convert = MapstructUtils.convert(list, WfFormVo.class); |
| | | ExcelUtil.exportExcel( convert, "æµç¨è¡¨å", WfFormVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨è¡¨å详ç»ä¿¡æ¯ |
| | | * @param formId ä¸»é® |
| | | */ |
| | | @GetMapping(value = "/{formId}") |
| | | public R getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") @PathVariable("formId") Long formId) { |
| | | return R.ok(formService.queryById(formId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨è¡¨å |
| | | */ |
| | | @PostMapping |
| | | public R add(@RequestBody WfFormBo bo) { |
| | | return toAjax(formService.insertForm(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨è¡¨å |
| | | */ |
| | | @PutMapping |
| | | public R edit(@RequestBody WfFormBo bo) { |
| | | return toAjax(formService.updateForm(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨è¡¨å |
| | | * @param formIds 主é®ä¸² |
| | | */ |
| | | @DeleteMapping("/{formIds}") |
| | | public R remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") @PathVariable Long[] formIds) { |
| | | return toAjax(formService.deleteWithValidByIds(Arrays.asList(formIds)) ? 1 : 0); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æè½½æµç¨è¡¨å |
| | | */ |
| | | @PostMapping("/addDeployForm") |
| | | public R addDeployForm(@RequestBody WfDeployForm deployForm) { |
| | | return toAjax(deployFormService.insertWfDeployForm(deployForm)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.service.IWfInstanceService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | | * 工使µæµç¨å®ä¾ç®¡ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/instance") |
| | | public class WfInstanceController { |
| | | |
| | | private final IWfInstanceService instanceService; |
| | | |
| | | /** |
| | | * æ¿æ´»ææèµ·æµç¨å®ä¾ |
| | | * |
| | | * @param state 1:æ¿æ´»,2:æèµ· |
| | | * @param instanceId æµç¨å®ä¾ID |
| | | */ |
| | | @PostMapping(value = "/updateState") |
| | | public R updateState(@RequestParam Integer state, @RequestParam String instanceId) { |
| | | instanceService.updateState(state, instanceId); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * ç»ææµç¨å®ä¾ |
| | | * |
| | | * @param bo æµç¨ä»»å¡ä¸å¡å¯¹è±¡ |
| | | */ |
| | | @PostMapping(value = "/stopProcessInstance") |
| | | public R stopProcessInstance(@RequestBody WfTaskBo bo) { |
| | | instanceService.stopProcessInstance(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¾ |
| | | * |
| | | * @param instanceId æµç¨å®ä¾ID |
| | | * @param deleteReason å é¤åå |
| | | */ |
| | | @Deprecated |
| | | @DeleteMapping(value = "/delete") |
| | | public R delete(@RequestParam String instanceId, String deleteReason) { |
| | | instanceService.delete(instanceId, deleteReason); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¾è¯¦æ
ä¿¡æ¯ |
| | | * |
| | | * @param procInsId æµç¨å®ä¾ID |
| | | * @param deployId æµç¨é¨ç½²ID |
| | | */ |
| | | @GetMapping("/detail") |
| | | public R detail(String procInsId, String deployId) { |
| | | return R.ok(instanceService.queryDetailProcess(procInsId, deployId)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | import org.ruoyi.common.excel.utils.ExcelUtil; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.WfCategory; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfModelBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCategoryVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfModelExportVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfModelVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfCategoryService; |
| | | import org.ruoyi.flowable.workflow.service.IWfModelService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 工使µæµç¨æ¨¡å管ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:09 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/model") |
| | | public class WfModelController extends BaseController { |
| | | |
| | | private final IWfModelService modelService; |
| | | private final IWfCategoryService categoryService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡åå表 |
| | | * |
| | | * @param modelBo æµç¨æ¨¡å对象 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<WfModelVo> list(WfModelBo modelBo, PageQuery pageQuery) { |
| | | return modelService.list(modelBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡åå表 |
| | | * |
| | | * @param modelBo æµç¨æ¨¡å对象 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping("/historyList") |
| | | public TableDataInfo<WfModelVo> historyList(WfModelBo modelBo, PageQuery pageQuery) { |
| | | return modelService.historyList(modelBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨æ¨¡å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param modelId 模åä¸»é® |
| | | */ |
| | | @GetMapping(value = "/{modelId}") |
| | | public R<WfModelVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") @PathVariable("modelId") String modelId) { |
| | | return R.ok(modelService.getModel(modelId)); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨è¡¨å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param modelId 模åä¸»é® |
| | | */ |
| | | @GetMapping(value = "/bpmnXml/{modelId}") |
| | | public R<String> getBpmnXml(@NotNull(message = "主é®ä¸è½ä¸ºç©º") @PathVariable("modelId") String modelId) { |
| | | return R.ok(modelService.queryBpmnXmlById(modelId),"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨æ¨¡å |
| | | */ |
| | | @PostMapping |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody WfModelBo modelBo) { |
| | | modelService.insertModel(modelBo); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨æ¨¡å |
| | | */ |
| | | @PutMapping |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfModelBo modelBo) { |
| | | modelService.updateModel(modelBo); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * ä¿åæµç¨æ¨¡å |
| | | */ |
| | | @PostMapping("/save") |
| | | public R<String> save(@RequestBody WfModelBo modelBo) { |
| | | modelService.saveModel(modelBo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * è®¾ä¸ºææ°æµç¨æ¨¡å |
| | | * @param modelId |
| | | * @return |
| | | */ |
| | | @PostMapping("/latest") |
| | | public R<?> latest(@RequestParam String modelId) { |
| | | modelService.latestModel(modelId); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨æ¨¡å |
| | | * |
| | | * @param modelIds æµç¨æ¨¡å主é®ä¸² |
| | | */ |
| | | @DeleteMapping("/{modelIds}") |
| | | public R<String> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") @PathVariable String[] modelIds) { |
| | | modelService.deleteByIds(Arrays.asList(modelIds)); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * é¨ç½²æµç¨æ¨¡å |
| | | * |
| | | * @param modelId æµç¨æ¨¡åä¸»é® |
| | | */ |
| | | @PostMapping("/deploy") |
| | | public R deployModel(@RequestParam String modelId) { |
| | | return toAjax(modelService.deployModel(modelId)); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµç¨æ¨¡åæ°æ® |
| | | */ |
| | | @PostMapping("/export") |
| | | public void export(WfModelBo modelBo, HttpServletResponse response) { |
| | | List<WfModelVo> list = modelService.list(modelBo); |
| | | List<WfModelExportVo> listVo = BeanUtil.copyToList(list, WfModelExportVo.class); |
| | | List<WfCategoryVo> categoryVos = categoryService.queryList(new WfCategory()); |
| | | Map<String, String> categoryMap = categoryVos.stream() |
| | | .collect(Collectors.toMap(WfCategoryVo::getCode, WfCategoryVo::getCategoryName)); |
| | | for (WfModelExportVo exportVo : listVo) { |
| | | exportVo.setCategoryName(categoryMap.get(exportVo.getCategory())); |
| | | } |
| | | List<WfModelExportVo> convert = MapstructUtils.convert(listVo, WfModelExportVo.class); |
| | | ExcelUtil.exportExcel(convert, "æµç¨æ¨¡åæ°æ®", WfModelExportVo.class, response); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.domain.model.LoginUser; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.excel.utils.ExcelUtil; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfCopyBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.*; |
| | | import org.ruoyi.flowable.workflow.service.IWfCopyService; |
| | | import org.ruoyi.flowable.workflow.service.IWfProcessService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 工使µæµç¨ç®¡ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/24 18:54 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/process") |
| | | public class WfProcessController extends BaseController { |
| | | |
| | | private final IWfProcessService processService; |
| | | private final IWfCopyService copyService; |
| | | |
| | | /** |
| | | * æ¥è¯¢å¯åèµ·æµç¨å表 |
| | | * |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping(value = "/list") |
| | | public TableDataInfo<WfDefinitionVo> startProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return processService.selectPageStartProcessList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * ææ¥æçæµç¨ |
| | | */ |
| | | @GetMapping(value = "/ownList") |
| | | public TableDataInfo<WfTaskVo> ownProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return processService.selectPageOwnProcessList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾
åå表 |
| | | */ |
| | | @GetMapping(value = "/todoList") |
| | | public TableDataInfo<WfTaskVo> todoProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return processService.selectPageTodoProcessList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾
ç¾å表 |
| | | * |
| | | * @param processQuery æµç¨ä¸å¡å¯¹è±¡ |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping(value = "/claimList") |
| | | public TableDataInfo<WfTaskVo> claimProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return processService.selectPageClaimProcessList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·åå·²åå表 |
| | | * |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping(value = "/finishedList") |
| | | public TableDataInfo<WfTaskVo> finishedProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | return processService.selectPageFinishedProcessList(processQuery, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·åæéå表 |
| | | * |
| | | * @param copyBo æµç¨æé对象 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | @GetMapping(value = "/copyList") |
| | | public TableDataInfo<WfCopyVo> copyProcessList(WfCopyBo copyBo, PageQuery pageQuery) { |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | if (ObjectUtil.isNotNull(loginUser)) |
| | | { |
| | | copyBo.setUserId(loginUser.getUserId()); |
| | | } |
| | | return copyService.selectPageList(copyBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå¯åèµ·æµç¨å表 |
| | | */ |
| | | @PostMapping("/startExport") |
| | | public void startExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
| | | List<WfDefinitionVo> list = processService.selectStartProcessList(processQuery); |
| | | |
| | | List<WfDefinitionVo> convert = MapstructUtils.convert(list, WfDefinitionVo.class); |
| | | ExcelUtil.exportExcel(convert, "å¯åèµ·æµç¨", WfDefinitionVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºææ¥ææµç¨å表 |
| | | */ |
| | | @PostMapping("/ownExport") |
| | | public void ownExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
| | | List<WfTaskVo> list = processService.selectOwnProcessList(processQuery); |
| | | List<WfOwnTaskExportVo> listVo = BeanUtil.copyToList(list, WfOwnTaskExportVo.class); |
| | | for (WfOwnTaskExportVo exportVo : listVo) { |
| | | exportVo.setStatus(ObjectUtil.isNull(exportVo.getFinishTime()) ? "è¿è¡ä¸" : "已宿"); |
| | | } |
| | | List<WfOwnTaskExportVo> convert = MapstructUtils.convert(listVo, WfOwnTaskExportVo.class); |
| | | ExcelUtil.exportExcel(convert, "ææ¥æçæµç¨", WfOwnTaskExportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå¾
åæµç¨å表 |
| | | */ |
| | | @PostMapping("/todoExport") |
| | | public void todoExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
| | | List<WfTaskVo> list = processService.selectTodoProcessList(processQuery); |
| | | List<WfTodoTaskExportVo> listVo = BeanUtil.copyToList(list, WfTodoTaskExportVo.class); |
| | | List<WfTodoTaskExportVo> convert = MapstructUtils.convert(listVo, WfTodoTaskExportVo.class); |
| | | ExcelUtil.exportExcel(convert, "å¾
åæµç¨", WfTodoTaskExportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå¾
ç¾æµç¨å表 |
| | | */ |
| | | @PostMapping("/claimExport") |
| | | public void claimExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
| | | List<WfTaskVo> list = processService.selectClaimProcessList(processQuery); |
| | | List<WfClaimTaskExportVo> listVo = BeanUtil.copyToList(list, WfClaimTaskExportVo.class); |
| | | |
| | | List<WfClaimTaskExportVo> convert = MapstructUtils.convert(listVo, WfClaimTaskExportVo.class); |
| | | ExcelUtil.exportExcel(convert, "å¾
ç¾æµç¨", WfClaimTaskExportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå·²åæµç¨å表 |
| | | */ |
| | | @PostMapping("/finishedExport") |
| | | public void finishedExport(@Validated ProcessQuery processQuery, HttpServletResponse response) { |
| | | List<WfTaskVo> list = processService.selectFinishedProcessList(processQuery); |
| | | List<WfFinishedTaskExportVo> listVo = BeanUtil.copyToList(list, WfFinishedTaskExportVo.class); |
| | | List<WfFinishedTaskExportVo> convert = MapstructUtils.convert(listVo, WfFinishedTaskExportVo.class); |
| | | ExcelUtil.exportExcel(convert, "已念ç¨", WfFinishedTaskExportVo.class, response); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæéæµç¨å表 |
| | | */ |
| | | @PostMapping("/copyExport") |
| | | public void copyExport(WfCopyBo copyBo, HttpServletResponse response) { |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | if (ObjectUtil.isNotNull(loginUser)) |
| | | { |
| | | copyBo.setUserId(loginUser.getUserId()); |
| | | } |
| | | List<WfCopyVo> list = copyService.selectList(copyBo); |
| | | List<WfCopyVo> convert = MapstructUtils.convert(list, WfCopyVo.class); |
| | | ExcelUtil.exportExcel(convert, "æéæµç¨", WfCopyVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨é¨ç½²å
³è表åä¿¡æ¯ |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param deployId æµç¨é¨ç½²id |
| | | */ |
| | | @GetMapping("/getProcessForm") |
| | | public R<?> getForm(@RequestParam(value = "definitionId") String definitionId, |
| | | @RequestParam(value = "deployId") String deployId, |
| | | @RequestParam(value = "procInsId", required = false) String procInsId) { |
| | | return R.ok(processService.selectFormContent(definitionId, deployId, procInsId)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æµç¨å®ä¹idå¯å¨æµç¨å®ä¾ |
| | | * |
| | | * @param processDefId æµç¨å®ä¹id |
| | | * @param variables åééå,json对象 |
| | | */ |
| | | @PostMapping("/start/{processDefId}") |
| | | public R start(@PathVariable(value = "processDefId") String processDefId, @RequestBody Map<String, Object> variables) { |
| | | processService.startProcessByDefId(processDefId, variables); |
| | | return R.ok("æµç¨å¯å¨æå"); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¾ |
| | | * |
| | | * @param instanceIds æµç¨å®ä¾ID串 |
| | | */ |
| | | @DeleteMapping("/instance/{instanceIds}") |
| | | public R<Void> delete(@PathVariable String[] instanceIds) { |
| | | processService.deleteProcessByIds(instanceIds); |
| | | return R.ok("æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 读åxmlæä»¶ |
| | | * @param processDefId æµç¨å®ä¹ID |
| | | */ |
| | | @GetMapping("/bpmnXml/{processDefId}") |
| | | public R<String> getBpmnXml(@PathVariable(value = "processDefId") String processDefId) { |
| | | return R.ok(processService.queryBpmnXmlById(processDefId),null ); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¯¦æ
ä¿¡æ¯ |
| | | * |
| | | * @param procInsId æµç¨å®ä¾ID |
| | | * @param taskId ä»»å¡ID |
| | | */ |
| | | @GetMapping("/detail") |
| | | public R detail(String procInsId, String taskId) { |
| | | return R.ok(processService.queryProcessDetail(procInsId, taskId)); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.controller; |
| | | |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.service.IWfTaskService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | |
| | | /** |
| | | * 工使µä»»å¡ç®¡ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/task") |
| | | public class WfTaskController { |
| | | |
| | | private final IWfTaskService flowTaskService; |
| | | |
| | | /** |
| | | * åæ¶æµç¨ |
| | | */ |
| | | @PostMapping(value = "/stopProcess") |
| | | public R stopProcess(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.stopProcess(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æ¤åæµç¨ |
| | | */ |
| | | @PostMapping(value = "/revokeProcess") |
| | | public R revokeProcess(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.revokeProcess(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨åé |
| | | * @param taskId æµç¨ä»»å¡Id |
| | | */ |
| | | @GetMapping(value = "/processVariables/{taskId}") |
| | | public R processVariables(@PathVariable(value = "taskId") String taskId) { |
| | | return R.ok(flowTaskService.getProcessVariables(taskId)); |
| | | } |
| | | |
| | | /** |
| | | * 审æ¹ä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/complete") |
| | | public R complete(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.complete(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * æç»ä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/reject") |
| | | public R taskReject(@RequestBody WfTaskBo taskBo) { |
| | | flowTaskService.taskReject(taskBo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * éåä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/return") |
| | | public R taskReturn(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.taskReturn(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * è·åææå¯åéçèç¹ |
| | | */ |
| | | @PostMapping(value = "/returnList") |
| | | public R findReturnTaskList(@RequestBody WfTaskBo bo) { |
| | | return R.ok(flowTaskService.findReturnTaskList(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä»»å¡ |
| | | */ |
| | | @DeleteMapping(value = "/delete") |
| | | public R delete(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.deleteTask(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 认é¢/ç¾æ¶ä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/claim") |
| | | public R claim(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.claim(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * åæ¶è®¤é¢/ç¾æ¶ä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/unClaim") |
| | | public R unClaim(@RequestBody WfTaskBo bo) { |
| | | flowTaskService.unClaim(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/delegate") |
| | | public R delegate(@RequestBody WfTaskBo bo) { |
| | | if (ObjectUtil.hasNull(bo.getTaskId(), bo.getUserId())) { |
| | | return R.fail("åæ°é误ï¼"); |
| | | } |
| | | flowTaskService.delegateTask(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | */ |
| | | @PostMapping(value = "/transfer") |
| | | public R transfer(@RequestBody WfTaskBo bo) { |
| | | if (ObjectUtil.hasNull(bo.getTaskId(), bo.getUserId())) { |
| | | return R.fail("åæ°é误ï¼"); |
| | | } |
| | | flowTaskService.transferTask(bo); |
| | | return R.ok(null,"æä½æå"); |
| | | } |
| | | |
| | | /** |
| | | * çææµç¨å¾ |
| | | * |
| | | * @param processId ä»»å¡ID |
| | | */ |
| | | @RequestMapping("/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(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * æµç¨å类对象 wf_category |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-15 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_category") |
| | | public class WfCategory extends BaseEntity { |
| | | |
| | | private static final long serialVersionUID=1L; |
| | | |
| | | /** |
| | | * åç±»ID |
| | | */ |
| | | @TableId(value = "category_id", type = IdType.AUTO) |
| | | private Long categoryId; |
| | | /** |
| | | * åç±»åç§° |
| | | */ |
| | | @NotBlank(message = "åç±»åç§°ä¸è½ä¸ºç©º") |
| | | private String categoryName; |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @NotBlank(message = "åç±»ç¼ç ä¸è½ä¸ºç©º") |
| | | private String code; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | /** |
| | | * å 餿 å¿ï¼0代表åå¨ 2代表å é¤ï¼ |
| | | */ |
| | | @TableLogic |
| | | private String delFlag; |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain; |
| | | |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * æµç¨æé对象 wf_copy |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-05-19 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_copy") |
| | | public class WfCopy extends BaseEntity { |
| | | |
| | | private static final long serialVersionUID=1L; |
| | | |
| | | /** |
| | | * æéä¸»é® |
| | | */ |
| | | @TableId(value = "copy_id", type = IdType.AUTO) |
| | | private Long copyId; |
| | | /** |
| | | * æéæ é¢ |
| | | */ |
| | | private String title; |
| | | /** |
| | | * æµç¨ä¸»é® |
| | | */ |
| | | private String processId; |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | private String processName; |
| | | /** |
| | | * æµç¨åç±»ä¸»é® |
| | | */ |
| | | private String categoryId; |
| | | /** |
| | | * é¨ç½²ä¸»é® |
| | | */ |
| | | private String deploymentId; |
| | | /** |
| | | * æµç¨å®ä¾ä¸»é® |
| | | */ |
| | | private String instanceId; |
| | | /** |
| | | * ä»»å¡ä¸»é® |
| | | */ |
| | | private String taskId; |
| | | /** |
| | | * ç¨æ·ä¸»é® |
| | | */ |
| | | private Long userId; |
| | | /** |
| | | * å起人Id |
| | | */ |
| | | private Long originatorId; |
| | | /** |
| | | * å起人åç§° |
| | | */ |
| | | private String originatorName; |
| | | /** |
| | | * å 餿 å¿ï¼0代表åå¨ 2代表å é¤ï¼ |
| | | */ |
| | | @TableLogic |
| | | private String delFlag; |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å
³è表å对象 sys_instance_form |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Data |
| | | @TableName("wf_deploy_form") |
| | | public class WfDeployForm { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨é¨ç½²ä¸»é® |
| | | */ |
| | | private String deployId; |
| | | |
| | | /** |
| | | * 表åKey |
| | | */ |
| | | private String formKey; |
| | | |
| | | /** |
| | | * èç¹Key |
| | | */ |
| | | private String nodeKey; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | private String formName; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | private String content; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * æµç¨è¡¨å对象 wf_form |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_form") |
| | | public class WfForm extends BaseEntity { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 表åä¸»é® |
| | | */ |
| | | @TableId(value = "form_id", type = IdType.AUTO) |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | private String content; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.base; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Entityåºç±» |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class BaseEntity implements Serializable |
| | | { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** æç´¢å¼ */ |
| | | @JsonIgnore |
| | | @TableField(exist = false) |
| | | private String searchValue; |
| | | |
| | | /** å建è
*/ |
| | | private String createBy; |
| | | |
| | | /** å建æ¶é´ */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | |
| | | /** æ´æ°è
*/ |
| | | private String updateBy; |
| | | |
| | | /** æ´æ°æ¶é´ */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date updateTime; |
| | | |
| | | /** 夿³¨ */ |
| | | private String remark; |
| | | |
| | | /** 请æ±åæ° */ |
| | | @JsonInclude(JsonInclude.Include.NON_EMPTY) |
| | | @TableField(exist = false) |
| | | private Map<String, Object> params; |
| | | |
| | | public String getSearchValue() |
| | | { |
| | | return searchValue; |
| | | } |
| | | |
| | | public void setSearchValue(String searchValue) |
| | | { |
| | | this.searchValue = searchValue; |
| | | } |
| | | |
| | | public String getCreateBy() |
| | | { |
| | | return createBy; |
| | | } |
| | | |
| | | public void setCreateBy(String createBy) |
| | | { |
| | | this.createBy = createBy; |
| | | } |
| | | |
| | | public Date getCreateTime() |
| | | { |
| | | return createTime; |
| | | } |
| | | |
| | | public void setCreateTime(Date createTime) |
| | | { |
| | | this.createTime = createTime; |
| | | } |
| | | |
| | | public String getUpdateBy() |
| | | { |
| | | return updateBy; |
| | | } |
| | | |
| | | public void setUpdateBy(String updateBy) |
| | | { |
| | | this.updateBy = updateBy; |
| | | } |
| | | |
| | | public Date getUpdateTime() |
| | | { |
| | | return updateTime; |
| | | } |
| | | |
| | | public void setUpdateTime(Date updateTime) |
| | | { |
| | | this.updateTime = updateTime; |
| | | } |
| | | |
| | | public String getRemark() |
| | | { |
| | | return remark; |
| | | } |
| | | |
| | | public void setRemark(String remark) |
| | | { |
| | | this.remark = remark; |
| | | } |
| | | |
| | | public Map<String, Object> getParams() |
| | | { |
| | | if (params == null) |
| | | { |
| | | params = new HashMap<>(); |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | public void setParams(Map<String, Object> params) |
| | | { |
| | | this.params = params; |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.bo; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * æµç¨æéä¸å¡å¯¹è±¡ wf_copy |
| | | * |
| | | * @author ruoyi |
| | | * @date 2022-05-19 |
| | | */ |
| | | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class WfCopyBo extends BaseEntity { |
| | | |
| | | /** |
| | | * æéä¸»é® |
| | | */ |
| | | @NotNull(message = "æé主é®ä¸è½ä¸ºç©º", groups = { EditGroup.class }) |
| | | private Long copyId; |
| | | |
| | | /** |
| | | * æéæ é¢ |
| | | */ |
| | | @NotNull(message = "æéæ é¢ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String title; |
| | | |
| | | /** |
| | | * æµç¨ä¸»é® |
| | | */ |
| | | @NotBlank(message = "æµç¨ä¸»é®ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String processId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @NotBlank(message = "æµç¨åç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String processName; |
| | | |
| | | /** |
| | | * æµç¨åç±»ä¸»é® |
| | | */ |
| | | @NotBlank(message = "æµç¨å类主é®ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String categoryId; |
| | | |
| | | /** |
| | | * ä»»å¡ä¸»é® |
| | | */ |
| | | @NotBlank(message = "ä»»å¡ä¸»é®ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * ç¨æ·ä¸»é® |
| | | */ |
| | | @NotNull(message = "ç¨æ·ä¸»é®ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private Long userId; |
| | | |
| | | /** |
| | | * å起人Id |
| | | */ |
| | | @NotNull(message = "å起人主é®ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private Long originatorId; |
| | | /** |
| | | * å起人åç§° |
| | | */ |
| | | @NotNull(message = "å起人åç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String originatorName; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.bo; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | |
| | | |
| | | /** |
| | | * æµç¨è®¾è®¡ä¸å¡å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Data |
| | | public class WfDesignerBo { |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @NotNull(message = "æµç¨åç§°", groups = { AddGroup.class, EditGroup.class }) |
| | | private String name; |
| | | |
| | | /** |
| | | * æµç¨åç±» |
| | | */ |
| | | @NotBlank(message = "æµç¨åç±»", groups = { AddGroup.class, EditGroup.class }) |
| | | private String category; |
| | | |
| | | /** |
| | | * XMLå符串 |
| | | */ |
| | | @NotBlank(message = "XMLå符串", groups = { AddGroup.class, EditGroup.class }) |
| | | private String xml; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.bo; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åä¸å¡å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class WfFormBo extends BaseEntity { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 表åä¸»é® |
| | | */ |
| | | @NotNull(message = "表åIDä¸è½ä¸ºç©º", groups = { EditGroup.class }) |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @NotBlank(message = "表ååç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | @NotBlank(message = "表åå
容ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String content; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.bo; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | |
| | | /** |
| | | * æµç¨æ¨¡å对象 |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:16 |
| | | */ |
| | | @Data |
| | | public class WfModelBo { |
| | | /** |
| | | * 模åä¸»é® |
| | | */ |
| | | @NotNull(message = "模å主é®ä¸è½ä¸ºç©º", groups = { EditGroup.class }) |
| | | private String modelId; |
| | | /** |
| | | * 模ååç§° |
| | | */ |
| | | @NotNull(message = "模ååç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String modelName; |
| | | /** |
| | | * 模åKey |
| | | */ |
| | | @NotNull(message = "模åKeyä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String modelKey; |
| | | /** |
| | | * æµç¨åç±» |
| | | */ |
| | | @NotBlank(message = "æµç¨åç±»ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String category; |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private String description; |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private Integer formType; |
| | | /** |
| | | * 表åä¸»é® |
| | | */ |
| | | private Long formId; |
| | | /** |
| | | * æµç¨xml |
| | | */ |
| | | private String bpmnXml; |
| | | /** |
| | | * æ¯å¦ä¿å为æ°çæ¬ |
| | | */ |
| | | private Boolean newVersion; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨ä»»å¡ä¸å¡å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Data |
| | | public class WfTaskBo { |
| | | /** |
| | | * ä»»å¡Id |
| | | */ |
| | | private String taskId; |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | private String taskName; |
| | | /** |
| | | * ç¨æ·Id |
| | | */ |
| | | private String userId; |
| | | /** |
| | | * ä»»å¡æè§ |
| | | */ |
| | | private String comment; |
| | | /** |
| | | * æµç¨å®ä¾Id |
| | | */ |
| | | private String procInsId; |
| | | /** |
| | | * èç¹ |
| | | */ |
| | | private String targetKey; |
| | | /** |
| | | * æµç¨åéä¿¡æ¯ |
| | | */ |
| | | private Map<String, Object> variables; |
| | | /** |
| | | * 审æ¹äºº |
| | | */ |
| | | private String assignee; |
| | | /** |
| | | * åé人 |
| | | */ |
| | | private List<String> candidateUsers; |
| | | /** |
| | | * 审æ¹ç» |
| | | */ |
| | | private List<String> candidateGroups; |
| | | /** |
| | | * æéç¨æ·Id |
| | | */ |
| | | private String copyUserIds; |
| | | /** |
| | | * ä¸ä¸èç¹å®¡æ¹äºº |
| | | */ |
| | | private String nextUserIds; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.dto; |
| | | |
| | | |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Data |
| | | @Builder |
| | | public class WfCommentDto implements Serializable { |
| | | |
| | | /** |
| | | * æè§ç±»å« 0 æ£å¸¸æè§ 1 éåæè§ 2 驳åæè§ |
| | | */ |
| | | private String type; |
| | | |
| | | /** |
| | | * æè§å
容 |
| | | */ |
| | | private String comment; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.dto; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:16 |
| | | */ |
| | | @Data |
| | | public class WfMetaInfoDto { |
| | | |
| | | /** |
| | | * å建è
ï¼usernameï¼ |
| | | */ |
| | | private String createUser; |
| | | |
| | | /** |
| | | * æµç¨æè¿° |
| | | */ |
| | | private String description; |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private Integer formType; |
| | | /** |
| | | * 表åç¼å· |
| | | */ |
| | | private Long formId; |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.dto; |
| | | |
| | | |
| | | import lombok.Data; |
| | | import org.ruoyi.system.domain.SysRole; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å¨æäººåãç» |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Data |
| | | public class WfNextDto implements Serializable { |
| | | |
| | | private String type; |
| | | |
| | | private String vars; |
| | | |
| | | private List<SysUser> userList; |
| | | |
| | | private List<SysRole> roleList; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | |
| | | |
| | | /** |
| | | * æµç¨åç±»è§å¾å¯¹è±¡ flow_category |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-15 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfCategoryVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * åç±»ID |
| | | */ |
| | | @ExcelProperty(value = "åç±»ID") |
| | | private Long categoryId; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | */ |
| | | @ExcelProperty(value = "åç±»åç§°") |
| | | private String categoryName; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åç±»ç¼ç ") |
| | | private String code; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "夿³¨") |
| | | private String remark; |
| | | |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * å¾
ç¾æµç¨å¯¹è±¡å¯¼åºVO |
| | | * |
| | | * @author konbai |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class WfClaimTaskExportVo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ç¼å· |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡ç¼å·") |
| | | private String taskId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String procDefName; |
| | | |
| | | /** |
| | | * ä»»å¡èç¹ |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡èç¹") |
| | | private String taskName; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨çæ¬") |
| | | private int procDefVersion; |
| | | |
| | | /** |
| | | * æµç¨å起人åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å起人") |
| | | private String startUserName; |
| | | |
| | | /** |
| | | * æ¥æ¶æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @ExcelProperty(value = "æ¥æ¶æ¶é´") |
| | | private Date createTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æµç¨æ¹å¤è§å¾å¯¹è±¡ |
| | | * |
| | | * @author konbai |
| | | * @createTime 2022/4/4 02:03 |
| | | */ |
| | | @Data |
| | | public class WfCommentVo { |
| | | |
| | | /** |
| | | * 审æ¹ç±»å« |
| | | */ |
| | | private String type; |
| | | |
| | | /** |
| | | * æ¹å¤å
容 |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * æ¹å¤æ¶é´ |
| | | */ |
| | | private Date time; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * æµç¨æéè§å¾å¯¹è±¡ wf_copy |
| | | * |
| | | * @author ruoyi |
| | | * @date 2022-05-19 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfCopyVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æéä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "æé主é®") |
| | | private Long copyId; |
| | | |
| | | /** |
| | | * æéæ é¢ |
| | | */ |
| | | @ExcelProperty(value = "æéæ é¢") |
| | | private String title; |
| | | |
| | | /** |
| | | * æµç¨ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "æµç¨ä¸»é®") |
| | | private String processId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String processName; |
| | | |
| | | /** |
| | | * æµç¨åç±»ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å类主é®") |
| | | private String categoryId; |
| | | |
| | | /** |
| | | * é¨ç½²ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "é¨ç½²ä¸»é®") |
| | | private String deploymentId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¾ä¸»é®") |
| | | private String instanceId; |
| | | |
| | | /** |
| | | * ä»»å¡ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡ä¸»é®") |
| | | private String taskId; |
| | | |
| | | /** |
| | | * ç¨æ·ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "ç¨æ·ä¸»é®") |
| | | private Long userId; |
| | | |
| | | /** |
| | | * å起人Id |
| | | */ |
| | | @ExcelProperty(value = "å起人主é®") |
| | | private Long originatorId; |
| | | |
| | | /** |
| | | * å起人åç§° |
| | | */ |
| | | @ExcelProperty(value = "å起人åç§°") |
| | | private String originatorName; |
| | | |
| | | /** |
| | | * æéæ¶é´ï¼å建æ¶é´ï¼ |
| | | */ |
| | | @ExcelProperty(value = "æéæ¶é´") |
| | | private Date createTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è§å¾å¯¹è±¡ workflow_definition |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-17 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfDefinitionVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ID |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¹ID") |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String processName; |
| | | |
| | | /** |
| | | * æµç¨Key |
| | | */ |
| | | @ExcelProperty(value = "æµç¨Key") |
| | | private String processKey; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åç±»ç¼ç ") |
| | | private String category; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "çæ¬") |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 表åID |
| | | */ |
| | | @ExcelProperty(value = "表åID") |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @ExcelProperty(value = "表ååç§°") |
| | | private String formName; |
| | | |
| | | /** |
| | | * é¨ç½²ID |
| | | */ |
| | | @ExcelProperty(value = "é¨ç½²ID") |
| | | private String deploymentId; |
| | | |
| | | /** |
| | | * æµç¨æ¯å¦æåï¼true:æèµ· false:æ¿æ´» ï¼ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨æ¯å¦æèµ·") |
| | | private Boolean suspended; |
| | | |
| | | /** |
| | | * é¨ç½²æ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "é¨ç½²æ¶é´") |
| | | private Date deploymentTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * é¨ç½²å®ä¾å表åå
³èè§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/7/17 18:29 |
| | | */ |
| | | @Data |
| | | public class WfDeployFormVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨é¨ç½²ä¸»é® |
| | | */ |
| | | private String deployId; |
| | | |
| | | /** |
| | | * 表åKey |
| | | */ |
| | | private String formKey; |
| | | |
| | | /** |
| | | * èç¹Key |
| | | */ |
| | | private String nodeKey; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | private String formName; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | private String content; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * æµç¨é¨ç½²è§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-06-30 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfDeployVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ID |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¹ID") |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String processName; |
| | | |
| | | /** |
| | | * æµç¨Key |
| | | */ |
| | | @ExcelProperty(value = "æµç¨Key") |
| | | private String processKey; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åç±»ç¼ç ") |
| | | private String category; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 表åID |
| | | */ |
| | | @ExcelProperty(value = "表åID") |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @ExcelProperty(value = "表ååç§°") |
| | | private String formName; |
| | | |
| | | /** |
| | | * é¨ç½²ID |
| | | */ |
| | | @ExcelProperty(value = "é¨ç½²ID") |
| | | private String deploymentId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ç¶æ: 1:æ¿æ´» , 2:䏿¢ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¹ç¶æ: 1:æ¿æ´» , 2:䏿¢") |
| | | private Boolean suspended; |
| | | |
| | | /** |
| | | * é¨ç½²æ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "é¨ç½²æ¶é´") |
| | | private Date deploymentTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.Data; |
| | | import org.ruoyi.flowable.core.FormConf; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨è¯¦æ
è§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/8/7 15:01 |
| | | */ |
| | | @Data |
| | | public class WfDetailVo { |
| | | |
| | | /** |
| | | * ä»»å¡è¡¨åä¿¡æ¯ |
| | | */ |
| | | private FormConf taskFormData; |
| | | |
| | | /** |
| | | * å岿µç¨èç¹ä¿¡æ¯ |
| | | */ |
| | | private List<WfProcNodeVo> historyProcNodeList; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åå表 |
| | | */ |
| | | private List<FormConf> processFormList; |
| | | |
| | | /** |
| | | * æµç¨XML |
| | | */ |
| | | private String bpmnXml; |
| | | |
| | | private WfViewerVo flowViewer; |
| | | |
| | | /** |
| | | * æ¯å¦åå¨ä»»å¡è¡¨åä¿¡æ¯ |
| | | * @return true:åå¨ï¼false:ä¸åå¨ |
| | | */ |
| | | public Boolean isExistTaskForm() { |
| | | return ObjectUtil.isNotEmpty(this.taskFormData); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 已念ç¨å¯¹è±¡å¯¼åºVO |
| | | * |
| | | * @author konbai |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class WfFinishedTaskExportVo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ç¼å· |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡ç¼å·") |
| | | private String taskId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String procDefName; |
| | | |
| | | /** |
| | | * ä»»å¡èç¹ |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡èç¹") |
| | | private String taskName; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨çæ¬") |
| | | private int procDefVersion; |
| | | |
| | | /** |
| | | * æµç¨å起人åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å起人") |
| | | private String startUserName; |
| | | |
| | | /** |
| | | * æ¥æ¶æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @ExcelProperty(value = "æ¥æ¶æ¶é´") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * å®¡æ¹æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @ExcelProperty(value = "å®¡æ¹æ¶é´") |
| | | private Date finishTime; |
| | | |
| | | /** |
| | | * ä»»å¡èæ¶ |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡èæ¶") |
| | | private String duration; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æµç¨åç±»è§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfFormVo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 表åä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "表åID") |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @ExcelProperty(value = "表ååç§°") |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | @ExcelProperty(value = "表åå
容") |
| | | private String content; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "夿³¨") |
| | | private String remark; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æµç¨æ¨¡å对象导åºVO |
| | | * |
| | | * @author konbai |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class WfModelExportVo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | /** |
| | | * 模åID |
| | | */ |
| | | @ExcelProperty(value = "模åID") |
| | | private String modelId; |
| | | /** |
| | | * 模åKey |
| | | */ |
| | | @ExcelProperty(value = "模åKey") |
| | | private String modelKey; |
| | | /** |
| | | * 模ååç§° |
| | | */ |
| | | @ExcelProperty(value = "模ååç§°") |
| | | private String modelName; |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åç±»ç¼ç ") |
| | | private String category; |
| | | /** |
| | | * æµç¨åç±» |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç±»") |
| | | private String categoryName; |
| | | /** |
| | | * 模åçæ¬ |
| | | */ |
| | | @ExcelProperty(value = "模åçæ¬") |
| | | private Integer version; |
| | | /** |
| | | * 模åæè¿° |
| | | */ |
| | | @ExcelProperty(value = "模åæè¿°") |
| | | private String description; |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "å建æ¶é´") |
| | | private Date createTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æµç¨æ¨¡åè§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:16 |
| | | */ |
| | | @Data |
| | | public class WfModelVo { |
| | | /** |
| | | * 模åID |
| | | */ |
| | | private String modelId; |
| | | /** |
| | | * 模ååç§° |
| | | */ |
| | | private String modelName; |
| | | /** |
| | | * 模åKey |
| | | */ |
| | | private String modelKey; |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | private String category; |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | private Integer version; |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private Integer formType; |
| | | /** |
| | | * 表åID |
| | | */ |
| | | private Long formId; |
| | | /** |
| | | * 模åæè¿° |
| | | */ |
| | | private String description; |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | /** |
| | | * æµç¨xml |
| | | */ |
| | | private String bpmnXml; |
| | | /** |
| | | * 表åå
容 |
| | | */ |
| | | private String content; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * ææ¥ææµç¨å¯¹è±¡å¯¼åºVO |
| | | * |
| | | * @author konbai |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class WfOwnTaskExportVo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ID |
| | | */ |
| | | @ExcelProperty(value = "æµç¨ç¼å·") |
| | | private String procInsId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String procDefName; |
| | | |
| | | /** |
| | | * æµç¨ç±»å« |
| | | */ |
| | | @ExcelProperty(value = "æµç¨ç±»å«") |
| | | private String category; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨çæ¬") |
| | | private int procDefVersion; |
| | | |
| | | /** |
| | | * æäº¤æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @ExcelProperty(value = "æäº¤æ¶é´") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨ç¶æ") |
| | | private String status; |
| | | |
| | | /** |
| | | * ä»»å¡èæ¶ |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡èæ¶") |
| | | private String duration; |
| | | |
| | | /** |
| | | * å½åèç¹ |
| | | */ |
| | | @ExcelProperty(value = "å½åèç¹") |
| | | private String taskName; |
| | | |
| | | /** |
| | | * ä»»å¡å®ææ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date finishTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import org.flowable.engine.task.Comment; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 工使µèç¹å
ç´ è§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/9/11 22:04 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfProcNodeVo implements Serializable { |
| | | /** |
| | | * æµç¨ID |
| | | */ |
| | | private String procDefId; |
| | | /** |
| | | * æ´»å¨ID |
| | | */ |
| | | private String activityId; |
| | | /** |
| | | * æ´»å¨åç§° |
| | | */ |
| | | private String activityName; |
| | | /** |
| | | * æ´»å¨ç±»å |
| | | */ |
| | | private String activityType; |
| | | /** |
| | | * æ´»å¨èæ¶ |
| | | */ |
| | | private String duration; |
| | | /** |
| | | * æ§è¡äººId |
| | | */ |
| | | private Long assigneeId; |
| | | /** |
| | | * æ§è¡äººåç§° |
| | | */ |
| | | private String assigneeName; |
| | | /** |
| | | * åéæ§è¡äºº |
| | | */ |
| | | private String candidate; |
| | | /** |
| | | * ä»»å¡æè§ |
| | | */ |
| | | private List<Comment> commentList; |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date endTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import org.flowable.engine.task.Comment; |
| | | import org.ruoyi.flowable.workflow.domain.dto.WfCommentDto; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 工使µä»»å¡è§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class WfTaskVo implements Serializable { |
| | | /** |
| | | * ä»»å¡ç¼å· |
| | | */ |
| | | private String taskId; |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | private String taskName; |
| | | /** |
| | | * ä»»å¡Key |
| | | */ |
| | | private String taskDefKey; |
| | | /** |
| | | * 任塿§è¡äººId |
| | | */ |
| | | private Long assigneeId; |
| | | /** |
| | | * é¨é¨åç§° |
| | | */ |
| | | @Deprecated |
| | | private String deptName; |
| | | /** |
| | | * æµç¨å起人é¨é¨åç§° |
| | | */ |
| | | @Deprecated |
| | | private String startDeptName; |
| | | /** |
| | | * 任塿§è¡äººåç§° |
| | | */ |
| | | private String assigneeName; |
| | | /** |
| | | * æµç¨å起人Id |
| | | */ |
| | | private Long startUserId; |
| | | /** |
| | | * æµç¨å起人åç§° |
| | | */ |
| | | private String startUserName; |
| | | /** |
| | | * æµç¨ç±»å |
| | | */ |
| | | private String category; |
| | | /** |
| | | * æµç¨åéä¿¡æ¯ |
| | | */ |
| | | private Object procVars; |
| | | /** |
| | | * å±é¨åéä¿¡æ¯ |
| | | */ |
| | | private Object taskLocalVars; |
| | | /** |
| | | * æµç¨é¨ç½²ç¼å· |
| | | */ |
| | | private String deployId; |
| | | /** |
| | | * æµç¨ID |
| | | */ |
| | | private String procDefId; |
| | | /** |
| | | * æµç¨key |
| | | */ |
| | | private String procDefKey; |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String procDefName; |
| | | /** |
| | | * æµç¨å®ä¹å
置使ç¨çæ¬ |
| | | */ |
| | | private int procDefVersion; |
| | | /** |
| | | * æµç¨å®ä¾ID |
| | | */ |
| | | private String procInsId; |
| | | /** |
| | | * å岿µç¨å®ä¾ID |
| | | */ |
| | | private String hisProcInsId; |
| | | /** |
| | | * ä»»å¡èæ¶ |
| | | */ |
| | | private String duration; |
| | | /** |
| | | * ä»»å¡æè§ |
| | | */ |
| | | private WfCommentDto comment; |
| | | /** |
| | | * ä»»å¡æè§ |
| | | */ |
| | | private List<Comment> commentList; |
| | | /** |
| | | * åéæ§è¡äºº |
| | | */ |
| | | private String candidate; |
| | | /** |
| | | * ä»»å¡å建æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | /** |
| | | * ä»»å¡å®ææ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date finishTime; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | private String processStatus; |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * å¾
åæµç¨å¯¹è±¡å¯¼åºVO |
| | | * |
| | | * @author konbai |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class WfTodoTaskExportVo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ç¼å· |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡ç¼å·") |
| | | private String taskId; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨åç§°") |
| | | private String procDefName; |
| | | |
| | | /** |
| | | * ä»»å¡èç¹ |
| | | */ |
| | | @ExcelProperty(value = "ä»»å¡èç¹") |
| | | private String taskName; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨çæ¬") |
| | | private int procDefVersion; |
| | | |
| | | /** |
| | | * æµç¨å起人åç§° |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å起人") |
| | | private String startUserName; |
| | | |
| | | /** |
| | | * æ¥æ¶æ¶é´ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @ExcelProperty(value = "æ¥æ¶æ¶é´") |
| | | private Date createTime; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * ä»»å¡è¿½è¸ªè§å¾å¯¹è±¡ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/1/8 19:42 |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @ExcelIgnoreUnannotated |
| | | public class WfViewerVo { |
| | | |
| | | /** |
| | | * è·åæµç¨å®ä¾çåå²èç¹ï¼å»éï¼ |
| | | */ |
| | | private Set<String> finishedTaskSet; |
| | | |
| | | /** |
| | | * 已宿 |
| | | */ |
| | | private Set<String> finishedSequenceFlowSet; |
| | | |
| | | /** |
| | | * è·åæµç¨å®ä¾å½åæ£å¨å¾
åçèç¹ï¼å»éï¼ |
| | | */ |
| | | private Set<String> unfinishedTaskSet; |
| | | |
| | | /** |
| | | * å·²æç» |
| | | */ |
| | | private Set<String> rejectedTaskSet; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.handler; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import org.flowable.bpmn.model.FlowElement; |
| | | import org.flowable.bpmn.model.UserTask; |
| | | import org.flowable.engine.delegate.DelegateExecution; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.common.constant.ProcessConstants; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | import org.ruoyi.system.domain.bo.SysUserBo; |
| | | import org.ruoyi.system.service.ISysUserService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * å¤å®ä¾å¤çç±» |
| | | * |
| | | * @author KonBAI |
| | | */ |
| | | @AllArgsConstructor |
| | | @Component("multiInstanceHandler") |
| | | public class MultiInstanceHandler { |
| | | @Autowired |
| | | private ISysUserService remoteUserService; |
| | | public Set<String> getUserIds(DelegateExecution execution) { |
| | | Set<String> candidateUserIds = new LinkedHashSet<>(); |
| | | FlowElement flowElement = execution.getCurrentFlowElement(); |
| | | if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask) { |
| | | UserTask userTask = (UserTask) flowElement; |
| | | String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); |
| | | if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) { |
| | | // æ·»å åéç¨æ·id |
| | | candidateUserIds.addAll(userTask.getCandidateUsers()); |
| | | } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) { |
| | | // è·åç»çIDï¼è§è²IDéåæé¨é¨IDéå |
| | | List<Long> groups = userTask.getCandidateGroups().stream() |
| | | .map(item -> Long.parseLong(item.substring(4))) |
| | | .collect(Collectors.toList()); |
| | | List<Long> userIds = new ArrayList<>(); |
| | | if ("ROLES".equals(dataType)) { |
| | | //todo éè¿è§è²idï¼è·åææç¨æ·idéå |
| | | R<List<SysUser>> userList = remoteUserService.selectUserByRoleIds(groups); |
| | | if(!ObjectUtil.isNull(userList) && !ObjectUtil.isNull(userList.getData())) { |
| | | List<SysUser> userListData = userList.getData(); |
| | | for(SysUser user : userListData) { |
| | | userIds.add(user.getUserId()); |
| | | } |
| | | } |
| | | } else if ("DEPTS".equals(dataType)) { |
| | | //todo éè¿é¨é¨idï¼è·åææç¨æ·idéå |
| | | R<List<SysUser>> userList = remoteUserService.selectUserByDeptIds(groups); |
| | | if(!ObjectUtil.isNull(userList) && ! ObjectUtil.isNull(userList.getData())) { |
| | | List<SysUser> userListData = userList.getData(); |
| | | for(SysUser user : userListData) { |
| | | userIds.add(user.getUserId()); |
| | | } |
| | | } |
| | | } |
| | | // æ·»å åéç¨æ·id |
| | | userIds.forEach(id -> candidateUserIds.add(String.valueOf(id))); |
| | | } |
| | | } |
| | | return candidateUserIds; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.mapper; |
| | | |
| | | |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.ruoyi.flowable.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.flowable.workflow.domain.WfCategory; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCategoryVo; |
| | | |
| | | /** |
| | | * æµç¨åç±»Mapperæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-15 |
| | | */ |
| | | @Mapper |
| | | public interface WfCategoryMapper extends BaseMapperPlus<WfCategoryMapper, WfCategory, WfCategoryVo> { |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.mapper; |
| | | |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.ruoyi.flowable.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.flowable.workflow.domain.WfCopy; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCopyVo; |
| | | |
| | | /** |
| | | * æµç¨æéMapperæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-05-19 |
| | | */ |
| | | @Mapper |
| | | public interface WfCopyMapper extends BaseMapperPlus<WfCopyMapper, WfCopy, WfCopyVo> { |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.mapper; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDeployFormVo; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å
³è表åMapperæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Mapper |
| | | public interface WfDeployFormMapper extends BaseMapperPlus<WfDeployFormMapper, WfDeployForm, WfDeployFormVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import org.ruoyi.flowable.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.flowable.workflow.domain.WfForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åMapperæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @Mapper |
| | | public interface WfFormMapper extends BaseMapperPlus<WfFormMapper, WfForm, WfFormVo> { |
| | | |
| | | List<WfFormVo> selectFormVoList(@Param(Constants.WRAPPER) Wrapper<WfForm> queryWrapper); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | import org.ruoyi.flowable.workflow.domain.WfCategory; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCategoryVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨åç±»Serviceæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-15 |
| | | */ |
| | | public interface IWfCategoryService { |
| | | /** |
| | | * æ¥è¯¢å个 |
| | | * @return |
| | | */ |
| | | WfCategoryVo queryById(Long categoryId); |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢å表 |
| | | */ |
| | | List<WfCategoryVo> queryList(WfCategory category); |
| | | |
| | | /** |
| | | * æ°å¢æµç¨åç±» |
| | | * |
| | | * @param category æµç¨åç±»ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | int insertCategory(WfCategory category); |
| | | |
| | | /** |
| | | * ç¼è¾æµç¨åç±» |
| | | * @param category æµç¨åç±»ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | int updateCategory(WfCategory category); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶å 餿°æ® |
| | | * @param ids 主é®éå |
| | | * @param isValid æ¯å¦æ ¡éª,true-å é¤åæ ¡éª,false-䏿 ¡éª |
| | | * @return ç»æ |
| | | */ |
| | | int deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | | /** |
| | | * æ ¡éªåç±»ç¼ç æ¯å¦å¯ä¸ |
| | | * |
| | | * @param category æµç¨åç±» |
| | | * @return ç»æ |
| | | */ |
| | | boolean checkCategoryCodeUnique(WfCategory category); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfCopyBo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCopyVo; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨æéServiceæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-05-19 |
| | | */ |
| | | public interface IWfCopyService { |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æé |
| | | * |
| | | * @param copyId æµç¨æéä¸»é® |
| | | * @return æµç¨æé |
| | | */ |
| | | WfCopyVo queryById(Long copyId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æéå表 |
| | | * |
| | | * @param wfCopy æµç¨æé |
| | | * @return æµç¨æééå |
| | | */ |
| | | TableDataInfo<WfCopyVo> selectPageList(WfCopyBo wfCopy, PageQuery pageQuery); |
| | | /** |
| | | * æ¥è¯¢æµç¨æéå表 |
| | | * |
| | | * @param wfCopy æµç¨æé |
| | | * @return æµç¨æééå |
| | | */ |
| | | List<WfCopyVo> selectList(WfCopyBo wfCopy); |
| | | |
| | | /** |
| | | * æé |
| | | * @param taskBo |
| | | * @return |
| | | */ |
| | | Boolean makeCopy(WfTaskBo taskBo); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å
³è表åServiceæ¥å£ |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | public interface IWfDeployFormService { |
| | | |
| | | /** |
| | | * æ°å¢æµç¨å®ä¾å
³è表å |
| | | * |
| | | * @param wfDeployForm æµç¨å®ä¾å
³è表å |
| | | * @return ç»æ |
| | | */ |
| | | int insertWfDeployForm(WfDeployForm wfDeployForm); |
| | | |
| | | /** |
| | | * ä¿åæµç¨å®ä¾å
³è表å |
| | | * @param deployId é¨ç½²ID |
| | | * @param bpmnModel bpmnModel对象 |
| | | * @return |
| | | */ |
| | | boolean saveInternalDeployForm(String deployId, BpmnModel bpmnModel); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æçç表å |
| | | * |
| | | * @param deployId |
| | | * @return |
| | | */ |
| | | @Deprecated |
| | | WfFormVo selectDeployFormByDeployId(String deployId); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDeployVo; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/30 9:03 |
| | | */ |
| | | public interface IWfDeployService { |
| | | |
| | | TableDataInfo<WfDeployVo> queryPageList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | TableDataInfo<WfDeployVo> queryPublishList(String processKey, PageQuery pageQuery); |
| | | |
| | | void updateState(String definitionId, String stateCode); |
| | | |
| | | String queryBpmnXmlById(String definitionId); |
| | | |
| | | void deleteByIds(List<String> deployIds); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfFormBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 表å |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | public interface IWfFormService { |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨å |
| | | * |
| | | * @param formId æµç¨è¡¨åID |
| | | * @return æµç¨è¡¨å |
| | | */ |
| | | WfFormVo queryById(Long formId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨åå表 |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return æµç¨è¡¨åéå |
| | | */ |
| | | TableDataInfo<WfFormVo> queryPageList(WfFormBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨åå表 |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return æµç¨è¡¨åéå |
| | | */ |
| | | List<WfFormVo> queryList(WfFormBo bo); |
| | | |
| | | /** |
| | | * æ°å¢æµç¨è¡¨å |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return ç»æ |
| | | */ |
| | | int insertForm(WfFormBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨è¡¨å |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return ç»æ |
| | | */ |
| | | int updateForm(WfFormBo bo); |
| | | |
| | | /** |
| | | * æ¹éå 餿µç¨è¡¨å |
| | | * |
| | | * @param formIds éè¦å é¤çæµç¨è¡¨åID |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> formIds); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | public interface IWfInstanceService { |
| | | |
| | | /** |
| | | * ç»ææµç¨å®ä¾ |
| | | * |
| | | * @param vo |
| | | */ |
| | | void stopProcessInstance(WfTaskBo 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); |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¯¦æ
ä¿¡æ¯ |
| | | * @param procInsId æµç¨å®ä¾ID |
| | | * @param deployId æµç¨é¨ç½²ID |
| | | */ |
| | | Map<String, Object> queryDetailProcess(String procInsId, String deployId); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfModelBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfModelVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:11 |
| | | */ |
| | | public interface IWfModelService { |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡åå表 |
| | | */ |
| | | TableDataInfo<WfModelVo> list(WfModelBo modelBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡åå表 |
| | | */ |
| | | List<WfModelVo> list(WfModelBo modelBo); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡åå表 |
| | | */ |
| | | TableDataInfo<WfModelVo> historyList(WfModelBo modelBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æ¨¡å详æ
ä¿¡æ¯ |
| | | */ |
| | | WfModelVo getModel(String modelId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨å详ç»ä¿¡æ¯ |
| | | */ |
| | | String queryBpmnXmlById(String modelId); |
| | | |
| | | /** |
| | | * æ°å¢æ¨¡åä¿¡æ¯ |
| | | */ |
| | | void insertModel(WfModelBo modelBo); |
| | | |
| | | /** |
| | | * ä¿®æ¹æ¨¡åä¿¡æ¯ |
| | | */ |
| | | void updateModel(WfModelBo modelBo); |
| | | |
| | | /** |
| | | * ä¿åæµç¨æ¨¡åä¿¡æ¯ |
| | | */ |
| | | void saveModel(WfModelBo modelBo); |
| | | |
| | | /** |
| | | * è®¾ä¸ºææ°æµç¨æ¨¡å |
| | | */ |
| | | void latestModel(String modelId); |
| | | |
| | | /** |
| | | * å 餿µç¨æ¨¡å |
| | | */ |
| | | void deleteByIds(Collection<String> ids); |
| | | |
| | | /** |
| | | * é¨ç½²æµç¨æ¨¡å |
| | | */ |
| | | boolean deployModel(String modelId); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | |
| | | import org.ruoyi.flowable.core.FormConf; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDefinitionVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDetailVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfTaskVo; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/24 18:57 |
| | | */ |
| | | public interface IWfProcessService { |
| | | |
| | | /** |
| | | * æ¥è¯¢å¯åèµ·æµç¨å表 |
| | | * @param pageQuery å页忰 |
| | | * @return |
| | | */ |
| | | TableDataInfo<WfDefinitionVo> selectPageStartProcessList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å¯åèµ·æµç¨å表 |
| | | */ |
| | | List<WfDefinitionVo> selectStartProcessList(ProcessQuery processQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æçæµç¨å表 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | TableDataInfo<WfTaskVo> selectPageOwnProcessList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æçæµç¨å表 |
| | | */ |
| | | List<WfTaskVo> selectOwnProcessList(ProcessQuery processQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ä»£åä»»å¡å表 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | TableDataInfo<WfTaskVo> selectPageTodoProcessList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ä»£åä»»å¡å表 |
| | | */ |
| | | List<WfTaskVo> selectTodoProcessList(ProcessQuery processQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å¾
ç¾ä»»å¡å表 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | TableDataInfo<WfTaskVo> selectPageClaimProcessList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å¾
ç¾ä»»å¡å表 |
| | | */ |
| | | List<WfTaskVo> selectClaimProcessList(ProcessQuery processQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²åä»»å¡å表 |
| | | * @param pageQuery å页忰 |
| | | */ |
| | | TableDataInfo<WfTaskVo> selectPageFinishedProcessList(ProcessQuery processQuery, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²åä»»å¡å表 |
| | | */ |
| | | List<WfTaskVo> selectFinishedProcessList(ProcessQuery processQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨é¨ç½²å
³è表åä¿¡æ¯ |
| | | * @param definitionId æµç¨å®ä¹ID |
| | | * @param deployId é¨ç½²ID |
| | | */ |
| | | FormConf selectFormContent(String definitionId, String deployId, String procInsId); |
| | | |
| | | /** |
| | | * å¯å¨æµç¨å®ä¾ |
| | | * @param procDefId æµç¨å®ä¹ID |
| | | * @param variables æ©å±åæ° |
| | | */ |
| | | void startProcessByDefId(String procDefId, Map<String, Object> variables); |
| | | |
| | | /** |
| | | * éè¿DefinitionKeyå¯å¨æµç¨ |
| | | * @param procDefKey æµç¨å®ä¹Key |
| | | * @param variables æ©å±åæ° |
| | | */ |
| | | void startProcessByDefKey(String procDefKey, Map<String, Object> variables); |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¾ |
| | | */ |
| | | void deleteProcessByIds(String[] instanceIds); |
| | | |
| | | |
| | | /** |
| | | * 读åxmlæä»¶ |
| | | * @param processDefId æµç¨å®ä¹ID |
| | | */ |
| | | String queryBpmnXmlById(String processDefId); |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨ä»»å¡è¯¦æ
ä¿¡æ¯ |
| | | * @param procInsId æµç¨å®ä¾ID |
| | | * @param taskId ä»»å¡ID |
| | | */ |
| | | WfDetailVo queryProcessDetail(String procInsId, String taskId); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service; |
| | | |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.flowable.bpmn.model.FlowElement; |
| | | import org.flowable.engine.runtime.ProcessInstance; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | public interface IWfTaskService { |
| | | |
| | | /** |
| | | * 审æ¹ä»»å¡ |
| | | * |
| | | * @param task 请æ±å®ä½åæ° |
| | | */ |
| | | void complete(WfTaskBo task); |
| | | |
| | | /** |
| | | * æç»ä»»å¡ |
| | | * |
| | | * @param taskBo |
| | | */ |
| | | void taskReject(WfTaskBo taskBo); |
| | | |
| | | |
| | | /** |
| | | * éåä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void taskReturn(WfTaskBo bo); |
| | | |
| | | /** |
| | | * è·åææå¯åéçèç¹ |
| | | * |
| | | * @param bo |
| | | * @return |
| | | */ |
| | | List<FlowElement> findReturnTaskList(WfTaskBo bo); |
| | | |
| | | /** |
| | | * å é¤ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void deleteTask(WfTaskBo bo); |
| | | |
| | | /** |
| | | * 认é¢/ç¾æ¶ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void claim(WfTaskBo bo); |
| | | |
| | | /** |
| | | * åæ¶è®¤é¢/ç¾æ¶ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void unClaim(WfTaskBo bo); |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void delegateTask(WfTaskBo bo); |
| | | |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | void transferTask(WfTaskBo bo); |
| | | |
| | | /** |
| | | * åæ¶ç³è¯· |
| | | * @param bo |
| | | * @return |
| | | */ |
| | | void stopProcess(WfTaskBo bo); |
| | | |
| | | /** |
| | | * æ¤åæµç¨ |
| | | * @param bo |
| | | * @return |
| | | */ |
| | | void revokeProcess(WfTaskBo bo); |
| | | |
| | | /** |
| | | * è·åæµç¨è¿ç¨å¾ |
| | | * @param processId |
| | | * @return |
| | | */ |
| | | InputStream diagram(String processId); |
| | | |
| | | /** |
| | | * è·åæµç¨åé |
| | | * @param taskId ä»»å¡ID |
| | | * @return æµç¨åé |
| | | */ |
| | | Map<String, Object> getProcessVariables(String taskId); |
| | | |
| | | /** |
| | | * å¯å¨ç¬¬ä¸ä¸ªä»»å¡ |
| | | * @param processInstance æµç¨å®ä¾ |
| | | * @param variables æµç¨åæ° |
| | | */ |
| | | void startFirstTask(ProcessInstance processInstance, Map<String, Object> variables); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.workflow.domain.WfCategory; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCategoryVo; |
| | | import org.ruoyi.flowable.workflow.mapper.WfCategoryMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfCategoryService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨åç±»Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-01-15 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfCategoryServiceImpl implements IWfCategoryService { |
| | | |
| | | private final WfCategoryMapper baseMapper; |
| | | |
| | | @Override |
| | | public WfCategoryVo queryById(Long categoryId){ |
| | | return baseMapper.selectVoById(categoryId); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public List<WfCategoryVo> queryList(WfCategory category) { |
| | | LambdaQueryWrapper<WfCategory> lqw = buildQueryWrapper(category); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<WfCategory> buildQueryWrapper(WfCategory category) { |
| | | Map<String, Object> params = category.getParams(); |
| | | LambdaQueryWrapper<WfCategory> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(category.getCategoryName()), WfCategory::getCategoryName, category.getCategoryName()); |
| | | lqw.eq(StringUtils.isNotBlank(category.getCode()), WfCategory::getCode, category.getCode()); |
| | | return lqw; |
| | | } |
| | | |
| | | @Override |
| | | public int insertCategory(WfCategory categoryBo) { |
| | | WfCategory add = BeanUtil.toBean(categoryBo, WfCategory.class); |
| | | return baseMapper.insert(add); |
| | | } |
| | | |
| | | @Override |
| | | public int updateCategory(WfCategory categoryBo) { |
| | | WfCategory update = BeanUtil.toBean(categoryBo, WfCategory.class); |
| | | return baseMapper.updateById(update); |
| | | } |
| | | |
| | | @Override |
| | | public int deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if(isValid){ |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªåç±»ç¼ç æ¯å¦å¯ä¸ |
| | | * |
| | | * @param category æµç¨åç±» |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public boolean checkCategoryCodeUnique(WfCategory category) { |
| | | boolean exist = baseMapper.exists(new LambdaQueryWrapper<WfCategory>() |
| | | .eq(WfCategory::getCode, category.getCode()) |
| | | .ne(ObjectUtil.isNotNull(category.getCategoryId()), WfCategory::getCategoryId, category.getCategoryId())); |
| | | return !exist; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import jakarta.annotation.Resource; |
| | | import org.ruoyi.common.core.domain.model.LoginUser; |
| | | import org.ruoyi.common.core.utils.ObjectUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.WfCopy; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfCopyBo; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfCopyVo; |
| | | import org.ruoyi.flowable.workflow.mapper.WfCopyMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfCopyService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.engine.HistoryService; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.repository.Deployment; |
| | | import org.springframework.stereotype.Service; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨æéServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author KonBAI |
| | | * @date 2022-05-19 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfCopyServiceImpl implements IWfCopyService { |
| | | |
| | | private final WfCopyMapper baseMapper; |
| | | |
| | | private final HistoryService historyService; |
| | | @Resource |
| | | protected RepositoryService repositoryService; |
| | | /** |
| | | * æ¥è¯¢æµç¨æé |
| | | * |
| | | * @param copyId æµç¨æéä¸»é® |
| | | * @return æµç¨æé |
| | | */ |
| | | @Override |
| | | public WfCopyVo queryById(Long copyId){ |
| | | return baseMapper.selectVoById(copyId); |
| | | } |
| | | /** |
| | | * æ¥è¯¢æµç¨æéå表 |
| | | * |
| | | * @param bo æµç¨æé |
| | | * @return æµç¨æé |
| | | */ |
| | | @Override |
| | | public TableDataInfo<WfCopyVo> selectPageList(WfCopyBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<WfCopy> lqw = buildQueryWrapper(bo); |
| | | lqw.orderByDesc(WfCopy::getCreateTime); |
| | | Page<WfCopyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æéå表 |
| | | * |
| | | * @param bo æµç¨æé |
| | | * @return æµç¨æé |
| | | */ |
| | | @Override |
| | | public List<WfCopyVo> selectList(WfCopyBo bo) { |
| | | LambdaQueryWrapper<WfCopy> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<WfCopy> buildQueryWrapper(WfCopyBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<WfCopy> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(bo.getUserId() != null, WfCopy::getUserId, bo.getUserId()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getProcessName()), WfCopy::getProcessName, bo.getProcessName()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getOriginatorName()), WfCopy::getOriginatorName, bo.getOriginatorName()); |
| | | return lqw; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean makeCopy(WfTaskBo taskBo) { |
| | | if (StringUtils.isBlank(taskBo.getCopyUserIds())) { |
| | | // è¥æéç¨æ·ä¸ºç©ºï¼åä¸éè¦å¤çï¼è¿åæå |
| | | return true; |
| | | } |
| | | HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(taskBo.getProcInsId()).singleResult(); |
| | | String[] ids = taskBo.getCopyUserIds().split(","); |
| | | List<WfCopy> copyList = new ArrayList<>(ids.length); |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | Long originatorId = null; |
| | | String originatorName = null; |
| | | if (ObjectUtils.isNotEmpty(loginUser)) |
| | | { |
| | | originatorId = loginUser.getUserId(); |
| | | originatorName = loginUser.getNickName(); |
| | | } |
| | | // æµç¨é¨ç½²å®ä¾ä¿¡æ¯ |
| | | Deployment deployment = repositoryService.createDeploymentQuery() |
| | | .deploymentId(historicProcessInstance.getDeploymentId()).singleResult(); |
| | | String title = historicProcessInstance.getProcessDefinitionName() + "-" + taskBo.getTaskName(); |
| | | for (String id : ids) { |
| | | Long userId = Long.valueOf(id); |
| | | WfCopy copy = new WfCopy(); |
| | | copy.setTitle(title); |
| | | copy.setProcessId(historicProcessInstance.getProcessDefinitionId()); |
| | | copy.setProcessName(historicProcessInstance.getProcessDefinitionName()); |
| | | copy.setDeploymentId(historicProcessInstance.getDeploymentId()); |
| | | copy.setInstanceId(taskBo.getProcInsId()); |
| | | copy.setTaskId(taskBo.getTaskId()); |
| | | copy.setUserId(userId); |
| | | copy.setOriginatorId(originatorId); |
| | | copy.setOriginatorName(originatorName); |
| | | copy.setCreateTime(new Date()); |
| | | copy.setCategoryId(deployment.getCategory()); |
| | | copyList.add(copy); |
| | | } |
| | | return baseMapper.insertBatch(copyList); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.utils.ModelUtils; |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.WfForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.mapper.WfDeployFormMapper; |
| | | import org.ruoyi.flowable.workflow.mapper.WfFormMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployFormService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | import org.flowable.bpmn.model.FlowNode; |
| | | import org.flowable.bpmn.model.StartEvent; |
| | | import org.flowable.bpmn.model.UserTask; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å
³è表åServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfDeployFormServiceImpl implements IWfDeployFormService { |
| | | |
| | | private final WfDeployFormMapper baseMapper; |
| | | |
| | | private final WfFormMapper formMapper; |
| | | |
| | | /** |
| | | * æ°å¢æµç¨å®ä¾å
³è表å |
| | | * |
| | | * @param deployForm æµç¨å®ä¾å
³è表å |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int insertWfDeployForm(WfDeployForm deployForm) { |
| | | // å é¤é¨ç½²æµç¨å表åçå
³èå
³ç³» |
| | | baseMapper.delete(new LambdaQueryWrapper<WfDeployForm>().eq(WfDeployForm::getDeployId, deployForm.getDeployId())); |
| | | // æ°å¢é¨ç½²æµç¨å表åå
³ç³» |
| | | return baseMapper.insert(deployForm); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean saveInternalDeployForm(String deployId, BpmnModel bpmnModel) { |
| | | List<WfDeployForm> deployFormList = new ArrayList<>(); |
| | | // è·åå¼å§èç¹ |
| | | StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel); |
| | | if (ObjectUtil.isNull(startEvent)) { |
| | | throw new RuntimeException("å¼å§èç¹ä¸åå¨ï¼è¯·æ£æ¥æµç¨è®¾è®¡æ¯å¦æè¯¯ï¼"); |
| | | } |
| | | // ä¿åå¼å§èç¹è¡¨åä¿¡æ¯ |
| | | WfDeployForm startDeployForm = buildDeployForm(deployId, startEvent); |
| | | if (ObjectUtil.isNotNull(startDeployForm)) { |
| | | deployFormList.add(startDeployForm); |
| | | } |
| | | // ä¿åç¨æ·èç¹è¡¨åä¿¡æ¯ |
| | | Collection<UserTask> userTasks = ModelUtils.getAllUserTaskEvent(bpmnModel); |
| | | if (CollUtil.isNotEmpty(userTasks)) { |
| | | for (UserTask userTask : userTasks) { |
| | | WfDeployForm userTaskDeployForm = buildDeployForm(deployId, userTask); |
| | | if (ObjectUtil.isNotNull(userTaskDeployForm)) { |
| | | deployFormList.add(userTaskDeployForm); |
| | | } |
| | | } |
| | | } |
| | | // æ¹éæ°å¢é¨ç½²æµç¨å表åå
³èä¿¡æ¯ |
| | | return baseMapper.insertBatch(deployFormList); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨æçç表å |
| | | * |
| | | * @param deployId |
| | | * @return |
| | | */ |
| | | @Override |
| | | public WfFormVo selectDeployFormByDeployId(String deployId) { |
| | | QueryWrapper<WfForm> wrapper = Wrappers.query(); |
| | | wrapper.eq("t2.deploy_id", deployId); |
| | | List<WfFormVo> list = formMapper.selectFormVoList(wrapper); |
| | | if (ObjectUtil.isNotEmpty(list)) { |
| | | if (list.size() != 1) { |
| | | throw new ServiceException("表åä¿¡æ¯æ¥è¯¢é误"); |
| | | } else { |
| | | return list.get(0); |
| | | } |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå»ºé¨ç½²è¡¨åå
³èä¿¡æ¯å¯¹è±¡ |
| | | * @param deployId é¨ç½²ID |
| | | * @param node èç¹ä¿¡æ¯ |
| | | * @return é¨ç½²è¡¨åå
³è对象ãè¥æ 表åä¿¡æ¯ï¼formKeyï¼ï¼åè¿ånull |
| | | */ |
| | | private WfDeployForm buildDeployForm(String deployId, FlowNode node) { |
| | | String formKey = ModelUtils.getFormKey(node); |
| | | if (StringUtils.isEmpty(formKey)) { |
| | | return null; |
| | | } |
| | | Long formId = Convert.toLong(StringUtils.substringAfter(formKey, "key_")); |
| | | WfForm wfForm = formMapper.selectById(formId); |
| | | if (ObjectUtil.isNull(wfForm)) { |
| | | throw new ServiceException("表åä¿¡æ¯æ¥è¯¢é误"); |
| | | } |
| | | WfDeployForm deployForm = new WfDeployForm(); |
| | | deployForm.setDeployId(deployId); |
| | | deployForm.setFormKey(formKey); |
| | | deployForm.setNodeKey(node.getId()); |
| | | deployForm.setFormName(wfForm.getFormName()); |
| | | deployForm.setNodeName(node.getName()); |
| | | deployForm.setContent(wfForm.getContent()); |
| | | return deployForm; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.io.IORuntimeException; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.utils.ProcessUtils; |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfDeployVo; |
| | | import org.ruoyi.flowable.workflow.mapper.WfDeployFormMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.common.engine.impl.db.SuspensionState; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.repository.Deployment; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.flowable.engine.repository.ProcessDefinitionQuery; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/30 9:04 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfDeployServiceImpl implements IWfDeployService { |
| | | |
| | | private final RepositoryService repositoryService; |
| | | private final WfDeployFormMapper deployFormMapper; |
| | | |
| | | @Override |
| | | public TableDataInfo<WfDeployVo> queryPageList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | // æµç¨å®ä¹åè¡¨æ°æ®æ¥è¯¢ |
| | | ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery() |
| | | .latestVersion() |
| | | .orderByProcessDefinitionKey() |
| | | .asc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(processDefinitionQuery, processQuery); |
| | | long pageTotal = processDefinitionQuery.count(); |
| | | if (pageTotal <= 0) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<ProcessDefinition> definitionList = processDefinitionQuery.listPage(offset, pageQuery.getPageSize()); |
| | | |
| | | List<WfDeployVo> deployVoList = new ArrayList<>(definitionList.size()); |
| | | for (ProcessDefinition processDefinition : definitionList) { |
| | | String deploymentId = processDefinition.getDeploymentId(); |
| | | Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult(); |
| | | WfDeployVo vo = new WfDeployVo(); |
| | | vo.setDefinitionId(processDefinition.getId()); |
| | | vo.setProcessKey(processDefinition.getKey()); |
| | | vo.setProcessName(processDefinition.getName()); |
| | | vo.setVersion(processDefinition.getVersion()); |
| | | vo.setCategory(processDefinition.getCategory()); |
| | | vo.setDeploymentId(processDefinition.getDeploymentId()); |
| | | vo.setSuspended(processDefinition.isSuspended()); |
| | | // æµç¨é¨ç½²ä¿¡æ¯ |
| | | vo.setCategory(deployment.getCategory()); |
| | | vo.setDeploymentTime(deployment.getDeploymentTime()); |
| | | deployVoList.add(vo); |
| | | } |
| | | Page<WfDeployVo> page = new Page<>(); |
| | | page.setRecords(deployVoList); |
| | | page.setTotal(pageTotal); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfDeployVo> queryPublishList(String processKey, PageQuery pageQuery) { |
| | | // å建æ¥è¯¢æ¡ä»¶ |
| | | ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionKey(processKey) |
| | | .orderByProcessDefinitionVersion() |
| | | .desc(); |
| | | long pageTotal = processDefinitionQuery.count(); |
| | | if (pageTotal <= 0) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | // æ ¹æ®æ¥è¯¢æ¡ä»¶ï¼æ¥è¯¢ææçæ¬ |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<ProcessDefinition> processDefinitionList = processDefinitionQuery |
| | | .listPage(offset, pageQuery.getPageSize()); |
| | | List<WfDeployVo> deployVoList = processDefinitionList.stream().map(item -> { |
| | | WfDeployVo vo = new WfDeployVo(); |
| | | vo.setDefinitionId(item.getId()); |
| | | vo.setProcessKey(item.getKey()); |
| | | vo.setProcessName(item.getName()); |
| | | vo.setVersion(item.getVersion()); |
| | | vo.setCategory(item.getCategory()); |
| | | vo.setDeploymentId(item.getDeploymentId()); |
| | | vo.setSuspended(item.isSuspended()); |
| | | return vo; |
| | | }).collect(Collectors.toList()); |
| | | Page<WfDeployVo> page = new Page<>(); |
| | | page.setRecords(deployVoList); |
| | | page.setTotal(pageTotal); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¿æ´»ææèµ·æµç¨ |
| | | * |
| | | * @param state ç¶æ |
| | | * @param definitionId æµç¨å®ä¹ID |
| | | */ |
| | | @Override |
| | | public void updateState(String definitionId, String state) { |
| | | if (SuspensionState.ACTIVE.toString().equals(state)) { |
| | | // æ¿æ´» |
| | | repositoryService.activateProcessDefinitionById(definitionId, true, null); |
| | | } else if (SuspensionState.SUSPENDED.toString().equals(state)) { |
| | | // æèµ· |
| | | repositoryService.suspendProcessDefinitionById(definitionId, true, null); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public String queryBpmnXmlById(String definitionId) { |
| | | InputStream inputStream = repositoryService.getProcessModel(definitionId); |
| | | try { |
| | | return IoUtil.readUtf8(inputStream); |
| | | } catch (IORuntimeException exception) { |
| | | throw new RuntimeException("å è½½xmlæä»¶å¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteByIds(List<String> deployIds) { |
| | | for (String deployId : deployIds) { |
| | | repositoryService.deleteDeployment(deployId, true); |
| | | deployFormMapper.delete(new LambdaQueryWrapper<WfDeployForm>().eq(WfDeployForm::getDeployId, deployId)); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.workflow.domain.WfForm; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfFormBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.mapper.WfFormMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfFormService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨è¡¨åServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/7 22:07 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfFormServiceImpl implements IWfFormService { |
| | | |
| | | private final WfFormMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨å |
| | | * |
| | | * @param formId æµç¨è¡¨åID |
| | | * @return æµç¨è¡¨å |
| | | */ |
| | | @Override |
| | | public WfFormVo queryById(Long formId) { |
| | | return baseMapper.selectVoById(formId); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨åå表 |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return æµç¨è¡¨å |
| | | */ |
| | | @Override |
| | | public TableDataInfo<WfFormVo> queryPageList(WfFormBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<WfForm> lqw = buildQueryWrapper(bo); |
| | | Page<WfFormVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨è¡¨åå表 |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return æµç¨è¡¨å |
| | | */ |
| | | @Override |
| | | public List<WfFormVo> queryList(WfFormBo bo) { |
| | | LambdaQueryWrapper<WfForm> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨è¡¨å |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public int insertForm(WfFormBo bo) { |
| | | WfForm wfForm = new WfForm(); |
| | | wfForm.setFormName(bo.getFormName()); |
| | | wfForm.setContent(bo.getContent()); |
| | | wfForm.setRemark(bo.getRemark()); |
| | | return baseMapper.insert(wfForm); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨è¡¨å |
| | | * |
| | | * @param bo æµç¨è¡¨å |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public int updateForm(WfFormBo bo) { |
| | | return baseMapper.update(new WfForm(), new LambdaUpdateWrapper<WfForm>() |
| | | .set(StrUtil.isNotBlank(bo.getFormName()), WfForm::getFormName, bo.getFormName()) |
| | | .set(StrUtil.isNotBlank(bo.getContent()), WfForm::getContent, bo.getContent()) |
| | | .set(StrUtil.isNotBlank(bo.getRemark()), WfForm::getRemark, bo.getRemark()) |
| | | .eq(WfForm::getFormId, bo.getFormId())); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå 餿µç¨è¡¨å |
| | | * |
| | | * @param ids éè¦å é¤çæµç¨è¡¨åID |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids) { |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | private LambdaQueryWrapper<WfForm> buildQueryWrapper(WfFormBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<WfForm> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getFormName()), WfForm::getFormName, bo.getFormName()); |
| | | return lqw; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.BetweenFormatter; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.common.constant.TaskConstants; |
| | | import org.ruoyi.flowable.factory.FlowServiceFactory; |
| | | import org.ruoyi.flowable.utils.JsonUtils; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfTaskVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployFormService; |
| | | import org.ruoyi.flowable.workflow.service.IWfInstanceService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.common.engine.api.FlowableObjectNotFoundException; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.task.Comment; |
| | | import org.flowable.identitylink.api.history.HistoricIdentityLink; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.ruoyi.system.domain.SysDept; |
| | | import org.ruoyi.system.domain.SysRole; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | import org.ruoyi.system.domain.vo.SysDeptVo; |
| | | import org.ruoyi.system.domain.vo.SysRoleVo; |
| | | import org.ruoyi.system.domain.vo.SysUserVo; |
| | | import org.ruoyi.system.service.ISysDeptService; |
| | | import org.ruoyi.system.service.ISysRoleService; |
| | | import org.ruoyi.system.service.ISysUserService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 工使µæµç¨å®ä¾ç®¡ç |
| | | * |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | @Slf4j |
| | | public class WfInstanceServiceImpl extends FlowServiceFactory implements IWfInstanceService { |
| | | |
| | | private final IWfDeployFormService deployFormService; |
| | | private final ISysUserService userService; |
| | | private final ISysRoleService roleService; |
| | | private final ISysDeptService deptService; |
| | | @Autowired |
| | | private ISysUserService remoteUserService; |
| | | |
| | | /** |
| | | * ç»ææµç¨å®ä¾ |
| | | * |
| | | * @param vo |
| | | */ |
| | | @Override |
| | | public void stopProcessInstance(WfTaskBo 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; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æµç¨å岿µè½¬è®°å½ |
| | | * |
| | | * @param procInsId æµç¨å®ä¾Id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Map<String, Object> queryDetailProcess(String procInsId, String deployId) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if (StringUtils.isNotBlank(procInsId)) { |
| | | List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .orderByHistoricTaskInstanceStartTime().desc() |
| | | .list(); |
| | | List<Comment> commentList = taskService.getProcessInstanceComments(procInsId); |
| | | List<WfTaskVo> taskVoList = new ArrayList<>(taskInstanceList.size()); |
| | | taskInstanceList.forEach(taskInstance -> { |
| | | WfTaskVo taskVo = new WfTaskVo(); |
| | | taskVo.setProcDefId(taskInstance.getProcessDefinitionId()); |
| | | taskVo.setTaskId(taskInstance.getId()); |
| | | taskVo.setTaskDefKey(taskInstance.getTaskDefinitionKey()); |
| | | taskVo.setTaskName(taskInstance.getName()); |
| | | taskVo.setCreateTime(taskInstance.getStartTime()); |
| | | taskVo.setFinishTime(taskInstance.getEndTime()); |
| | | if (StringUtils.isNotBlank(taskInstance.getAssignee())) { |
| | | Long userId = Long.parseLong(taskInstance.getAssignee()); |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | taskVo.setAssigneeId(userId); |
| | | taskVo.setAssigneeName(user.getNickName()); |
| | | } |
| | | } |
| | | // å±ç¤ºå®¡æ¹äººå |
| | | List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(taskInstance.getId()); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | for (HistoricIdentityLink identityLink : linksForTask) { |
| | | if ("candidate".equals(identityLink.getType())) { |
| | | if (StringUtils.isNotBlank(identityLink.getUserId())) { |
| | | Long userId = Long.parseLong(identityLink.getUserId()); |
| | | String nickName =""; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | stringBuilder.append(nickName).append(","); |
| | | } |
| | | if (StringUtils.isNotBlank(identityLink.getGroupId())) { |
| | | if (identityLink.getGroupId().startsWith(TaskConstants.ROLE_GROUP_PREFIX)) { |
| | | Long roleId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.ROLE_GROUP_PREFIX)); |
| | | //finish do æ¥è¯¢è§è²åç§° |
| | | SysRoleVo roleR=roleService.selectRoleById(roleId); |
| | | if (!ObjectUtil.isNull(roleR)) { |
| | | stringBuilder.append(roleR.getRoleName()).append(","); |
| | | } |
| | | } else if (identityLink.getGroupId().startsWith(TaskConstants.DEPT_GROUP_PREFIX)) { |
| | | Long deptId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.DEPT_GROUP_PREFIX)); |
| | | //finish do æ¥è¯¢é¨é¨åç§° |
| | | SysDeptVo deptR=deptService.selectDeptById(deptId); |
| | | if (!ObjectUtil.isNull(deptR)) { |
| | | stringBuilder.append(deptR.getDeptName()).append(","); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (StringUtils.isNotBlank(stringBuilder)) { |
| | | taskVo.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1)); |
| | | } |
| | | if (ObjectUtil.isNotNull(taskInstance.getDurationInMillis())) { |
| | | taskVo.setDuration(DateUtil.formatBetween(taskInstance.getDurationInMillis(), BetweenFormatter.Level.SECOND)); |
| | | } |
| | | // è·åæè§è¯è®ºå
容 |
| | | if (CollUtil.isNotEmpty(commentList)) { |
| | | List<Comment> comments = new ArrayList<>(); |
| | | // commentList.stream().filter(comment -> taskInstance.getId().equals(comment.getTaskId())).collect(Collectors.toList()); |
| | | for (Comment comment : commentList) { |
| | | if (comment.getTaskId().equals(taskInstance.getId())) { |
| | | comments.add(comment); |
| | | // taskVo.setComment(WfCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build()); |
| | | } |
| | | } |
| | | taskVo.setCommentList(comments); |
| | | } |
| | | taskVoList.add(taskVo); |
| | | }); |
| | | map.put("flowList", taskVoList); |
| | | // // æ¥è¯¢å½å任塿¯å¦å®æ |
| | | // List<Task> taskList = taskService.createTaskQuery().processInstanceId(procInsId).list(); |
| | | // if (CollectionUtils.isNotEmpty(taskList)) { |
| | | // map.put("finished", true); |
| | | // } else { |
| | | // map.put("finished", false); |
| | | // } |
| | | } |
| | | // ç¬¬ä¸æ¬¡ç³è¯·è·ååå§å表å |
| | | if (StringUtils.isNotBlank(deployId)) { |
| | | WfFormVo formVo = deployFormService.selectDeployFormByDeployId(deployId); |
| | | if (Objects.isNull(formVo)) { |
| | | throw new ServiceException("请å
é
ç½®æµç¨è¡¨å"); |
| | | } |
| | | map.put("formData", JsonUtils.parseObject(formVo.getContent(), Map.class)); |
| | | } |
| | | return map; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.ruoyi.common.core.domain.model.LoginUser; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.flowable.common.constant.ProcessConstants; |
| | | import org.ruoyi.flowable.common.enums.FormType; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.factory.FlowServiceFactory; |
| | | import org.ruoyi.flowable.utils.JsonUtils; |
| | | import org.ruoyi.flowable.utils.ModelUtils; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfModelBo; |
| | | import org.ruoyi.flowable.workflow.domain.dto.WfMetaInfoDto; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfFormVo; |
| | | import org.ruoyi.flowable.workflow.domain.vo.WfModelVo; |
| | | import org.ruoyi.flowable.workflow.service.IWfDeployFormService; |
| | | import org.ruoyi.flowable.workflow.service.IWfFormService; |
| | | import org.ruoyi.flowable.workflow.service.IWfModelService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | import org.flowable.bpmn.model.StartEvent; |
| | | import org.flowable.engine.repository.Deployment; |
| | | import org.flowable.engine.repository.Model; |
| | | import org.flowable.engine.repository.ModelQuery; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/6/21 9:11 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | @Slf4j |
| | | public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelService { |
| | | |
| | | private final IWfFormService formService; |
| | | private final IWfDeployFormService deployFormService; |
| | | |
| | | @Override |
| | | public TableDataInfo<WfModelVo> list(WfModelBo modelBo, PageQuery pageQuery) { |
| | | ModelQuery modelQuery = repositoryService.createModelQuery().latestVersion().orderByCreateTime().desc(); |
| | | // æå»ºæ¥è¯¢æ¡ä»¶ |
| | | if (StringUtils.isNotBlank(modelBo.getModelKey())) { |
| | | modelQuery.modelKey(modelBo.getModelKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getModelName())) { |
| | | modelQuery.modelNameLike("%" + modelBo.getModelName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getCategory())) { |
| | | modelQuery.modelCategory(modelBo.getCategory()); |
| | | } |
| | | // æ§è¡æ¥è¯¢ |
| | | long pageTotal = modelQuery.count(); |
| | | if (pageTotal <= 0) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<Model> modelList = modelQuery.listPage(offset, pageQuery.getPageSize()); |
| | | List<WfModelVo> modelVoList = new ArrayList<>(modelList.size()); |
| | | modelList.forEach(model -> { |
| | | WfModelVo modelVo = new WfModelVo(); |
| | | modelVo.setModelId(model.getId()); |
| | | modelVo.setModelName(model.getName()); |
| | | modelVo.setModelKey(model.getKey()); |
| | | modelVo.setCategory(model.getCategory()); |
| | | modelVo.setCreateTime(model.getCreateTime()); |
| | | modelVo.setVersion(model.getVersion()); |
| | | WfMetaInfoDto metaInfo = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class); |
| | | if (metaInfo != null) { |
| | | modelVo.setDescription(metaInfo.getDescription()); |
| | | modelVo.setFormType(metaInfo.getFormType()); |
| | | modelVo.setFormId(metaInfo.getFormId()); |
| | | } |
| | | modelVoList.add(modelVo); |
| | | }); |
| | | Page<WfModelVo> page = new Page<>(); |
| | | page.setRecords(modelVoList); |
| | | page.setTotal(pageTotal); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfModelVo> list(WfModelBo modelBo) { |
| | | ModelQuery modelQuery = repositoryService.createModelQuery().latestVersion().orderByCreateTime().desc(); |
| | | // æå»ºæ¥è¯¢æ¡ä»¶ |
| | | if (StringUtils.isNotBlank(modelBo.getModelKey())) { |
| | | modelQuery.modelKey(modelBo.getModelKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getModelName())) { |
| | | modelQuery.modelNameLike("%" + modelBo.getModelName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getCategory())) { |
| | | modelQuery.modelCategory(modelBo.getCategory()); |
| | | } |
| | | List<Model> modelList = modelQuery.list(); |
| | | List<WfModelVo> modelVoList = new ArrayList<>(modelList.size()); |
| | | modelList.forEach(model -> { |
| | | WfModelVo modelVo = new WfModelVo(); |
| | | modelVo.setModelId(model.getId()); |
| | | modelVo.setModelName(model.getName()); |
| | | modelVo.setModelKey(model.getKey()); |
| | | modelVo.setCategory(model.getCategory()); |
| | | modelVo.setCreateTime(model.getCreateTime()); |
| | | modelVo.setVersion(model.getVersion()); |
| | | WfMetaInfoDto metaInfo = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class); |
| | | if (metaInfo != null) { |
| | | modelVo.setDescription(metaInfo.getDescription()); |
| | | modelVo.setFormType(metaInfo.getFormType()); |
| | | modelVo.setFormId(metaInfo.getFormId()); |
| | | } |
| | | modelVoList.add(modelVo); |
| | | }); |
| | | return modelVoList; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfModelVo> historyList(WfModelBo modelBo, PageQuery pageQuery) { |
| | | ModelQuery modelQuery = repositoryService.createModelQuery() |
| | | .modelKey(modelBo.getModelKey()) |
| | | .orderByModelVersion() |
| | | .desc(); |
| | | // æ§è¡æ¥è¯¢ï¼ä¸æ¾ç¤ºææ°çï¼-1ï¼ |
| | | long pageTotal = modelQuery.count() - 1; |
| | | if (pageTotal <= 0) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | // offset+1ï¼å»æææ°ç |
| | | int offset = 1 + pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<Model> modelList = modelQuery.listPage(offset, pageQuery.getPageSize()); |
| | | List<WfModelVo> modelVoList = new ArrayList<>(modelList.size()); |
| | | modelList.forEach(model -> { |
| | | WfModelVo modelVo = new WfModelVo(); |
| | | modelVo.setModelId(model.getId()); |
| | | modelVo.setModelName(model.getName()); |
| | | modelVo.setModelKey(model.getKey()); |
| | | modelVo.setCategory(model.getCategory()); |
| | | modelVo.setCreateTime(model.getCreateTime()); |
| | | modelVo.setVersion(model.getVersion()); |
| | | WfMetaInfoDto metaInfo = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class); |
| | | if (metaInfo != null) { |
| | | modelVo.setDescription(metaInfo.getDescription()); |
| | | modelVo.setFormType(metaInfo.getFormType()); |
| | | modelVo.setFormId(metaInfo.getFormId()); |
| | | } |
| | | modelVoList.add(modelVo); |
| | | }); |
| | | Page<WfModelVo> page = new Page<>(); |
| | | page.setRecords(modelVoList); |
| | | page.setTotal(pageTotal); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public WfModelVo getModel(String modelId) { |
| | | // è·åæµç¨æ¨¡å |
| | | Model model = repositoryService.getModel(modelId); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | // è·åæµç¨å¾ |
| | | String bpmnXml = queryBpmnXmlById(modelId); |
| | | WfModelVo modelVo = new WfModelVo(); |
| | | modelVo.setModelId(model.getId()); |
| | | modelVo.setModelName(model.getName()); |
| | | modelVo.setModelKey(model.getKey()); |
| | | modelVo.setCategory(model.getCategory()); |
| | | modelVo.setCreateTime(model.getCreateTime()); |
| | | modelVo.setVersion(model.getVersion()); |
| | | modelVo.setBpmnXml(bpmnXml); |
| | | WfMetaInfoDto metaInfo = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class); |
| | | if (metaInfo != null) { |
| | | modelVo.setDescription(metaInfo.getDescription()); |
| | | modelVo.setFormType(metaInfo.getFormType()); |
| | | modelVo.setFormId(metaInfo.getFormId()); |
| | | if (FormType.PROCESS.getType().equals(metaInfo.getFormType())) { |
| | | WfFormVo wfFormVo = formService.queryById(metaInfo.getFormId()); |
| | | modelVo.setContent(wfFormVo.getContent()); |
| | | } |
| | | } |
| | | return modelVo; |
| | | } |
| | | |
| | | @Override |
| | | public String queryBpmnXmlById(String modelId) { |
| | | byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId); |
| | | return StrUtil.utf8Str(bpmnBytes); |
| | | } |
| | | |
| | | @Override |
| | | public void insertModel(WfModelBo modelBo) { |
| | | Model model = repositoryService.newModel(); |
| | | model.setName(modelBo.getModelName()); |
| | | model.setKey(modelBo.getModelKey()); |
| | | model.setCategory(modelBo.getCategory()); |
| | | String metaInfo = buildMetaInfo(new WfMetaInfoDto(), modelBo.getDescription()); |
| | | model.setMetaInfo(metaInfo); |
| | | // ä¿åæµç¨æ¨¡å |
| | | repositoryService.saveModel(model); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateModel(WfModelBo modelBo) { |
| | | // æ ¹æ®æ¨¡åKeyæ¥è¯¢æ¨¡åä¿¡æ¯ |
| | | Model model = repositoryService.getModel(modelBo.getModelId()); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | model.setCategory(modelBo.getCategory()); |
| | | WfMetaInfoDto metaInfoDto = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class); |
| | | String metaInfo = buildMetaInfo(metaInfoDto, modelBo.getDescription()); |
| | | model.setMetaInfo(metaInfo); |
| | | // ä¿åæµç¨æ¨¡å |
| | | repositoryService.saveModel(model); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveModel(WfModelBo modelBo) { |
| | | // æ¥è¯¢æ¨¡åä¿¡æ¯ |
| | | Model model = repositoryService.getModel(modelBo.getModelId()); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | BpmnModel bpmnModel = ModelUtils.getBpmnModel(modelBo.getBpmnXml()); |
| | | if (ObjectUtil.isEmpty(bpmnModel)) { |
| | | throw new RuntimeException("è·å模å设计失败ï¼"); |
| | | } |
| | | String processName = bpmnModel.getMainProcess().getName(); |
| | | // è·åå¼å§èç¹ |
| | | StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel); |
| | | if (ObjectUtil.isNull(startEvent)) { |
| | | throw new RuntimeException("å¼å§èç¹ä¸åå¨ï¼è¯·æ£æ¥æµç¨è®¾è®¡æ¯å¦æè¯¯ï¼"); |
| | | } |
| | | // è·åå¼å§èç¹é
ç½®ç表åKey |
| | | if (StrUtil.isBlank(startEvent.getFormKey())) { |
| | | throw new RuntimeException("请é
ç½®æµç¨è¡¨å"); |
| | | } |
| | | Model newModel; |
| | | if (Boolean.TRUE.equals(modelBo.getNewVersion())) { |
| | | newModel = repositoryService.newModel(); |
| | | newModel.setName(processName); |
| | | newModel.setKey(model.getKey()); |
| | | newModel.setCategory(model.getCategory()); |
| | | newModel.setMetaInfo(model.getMetaInfo()); |
| | | newModel.setVersion(model.getVersion() + 1); |
| | | } else { |
| | | newModel = model; |
| | | // 设置æµç¨åç§° |
| | | newModel.setName(processName); |
| | | } |
| | | // ä¿åæµç¨æ¨¡å |
| | | repositoryService.saveModel(newModel); |
| | | // ä¿å BPMN XML |
| | | byte[] bpmnXmlBytes = StringUtils.getBytes(modelBo.getBpmnXml(), StandardCharsets.UTF_8); |
| | | repositoryService.addModelEditorSource(newModel.getId(), bpmnXmlBytes); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void latestModel(String modelId) { |
| | | // è·åæµç¨æ¨¡å |
| | | Model model = repositoryService.getModel(modelId); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | Integer latestVersion = repositoryService.createModelQuery() |
| | | .modelKey(model.getKey()) |
| | | .latestVersion() |
| | | .singleResult() |
| | | .getVersion(); |
| | | if (model.getVersion().equals(latestVersion)) { |
| | | throw new RuntimeException("å½åçæ¬å·²æ¯ææ°çï¼"); |
| | | } |
| | | // è·å BPMN XML |
| | | byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId); |
| | | Model newModel = repositoryService.newModel(); |
| | | newModel.setName(model.getName()); |
| | | newModel.setKey(model.getKey()); |
| | | newModel.setCategory(model.getCategory()); |
| | | newModel.setMetaInfo(model.getMetaInfo()); |
| | | newModel.setVersion(latestVersion + 1); |
| | | // ä¿åæµç¨æ¨¡å |
| | | repositoryService.saveModel(newModel); |
| | | // ä¿å BPMN XML |
| | | repositoryService.addModelEditorSource(newModel.getId(), bpmnBytes); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteByIds(Collection<String> ids) { |
| | | ids.forEach(id -> { |
| | | Model model = repositoryService.getModel(id); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | repositoryService.deleteModel(id); |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deployModel(String modelId) { |
| | | // è·åæµç¨æ¨¡å |
| | | Model model = repositoryService.getModel(modelId); |
| | | if (ObjectUtil.isNull(model)) { |
| | | throw new RuntimeException("æµç¨æ¨¡åä¸åå¨ï¼"); |
| | | } |
| | | // è·åæµç¨å¾ |
| | | byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId); |
| | | if (ArrayUtil.isEmpty(bpmnBytes)) { |
| | | throw new RuntimeException("请å
设计æµç¨å¾ï¼"); |
| | | } |
| | | String bpmnXml = StringUtils.toEncodedString(bpmnBytes, StandardCharsets.UTF_8); |
| | | BpmnModel bpmnModel = ModelUtils.getBpmnModel(bpmnXml); |
| | | String processName = model.getName() + ProcessConstants.SUFFIX; |
| | | // é¨ç½²æµç¨ |
| | | Deployment deployment = repositoryService.createDeployment() |
| | | .name(model.getName()) |
| | | .key(model.getKey()) |
| | | .category(model.getCategory()) |
| | | .addBytes(processName, bpmnBytes) |
| | | .deploy(); |
| | | ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery() |
| | | .deploymentId(deployment.getId()) |
| | | .singleResult(); |
| | | // ä¿®æ¹æµç¨å®ä¹çåç±»ï¼ä¾¿äºæç´¢æµç¨ |
| | | repositoryService.setProcessDefinitionCategory(procDef.getId(), model.getCategory()); |
| | | // ä¿åé¨ç½²è¡¨å |
| | | return deployFormService.saveInternalDeployForm(deployment.getId(), bpmnModel); |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæ¨¡åæ©å±ä¿¡æ¯ |
| | | * @return |
| | | */ |
| | | private String buildMetaInfo(WfMetaInfoDto metaInfo, String description) { |
| | | // åªæéç©ºï¼æè¿è¡è®¾ç½®ï¼é¿å
æ´æ°æ¶çè¦ç |
| | | if (StringUtils.isNotEmpty(description)) { |
| | | metaInfo.setDescription(description); |
| | | } |
| | | if (StringUtils.isNotEmpty(metaInfo.getCreateUser())) { |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | if (ObjectUtil.isNotNull(loginUser)){ |
| | | metaInfo.setCreateUser(loginUser.getUsername()); |
| | | } |
| | | } |
| | | return JsonUtils.toJsonString(metaInfo); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.date.BetweenFormatter; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.io.IORuntimeException; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.utils.DateUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.flowable.common.constant.ProcessConstants; |
| | | import org.ruoyi.flowable.common.constant.TaskConstants; |
| | | import org.ruoyi.flowable.common.enums.ProcessStatus; |
| | | import org.ruoyi.flowable.core.FormConf; |
| | | import org.ruoyi.flowable.core.domain.ProcessQuery; |
| | | import org.ruoyi.flowable.core.domain.model.PageQuery; |
| | | import org.ruoyi.flowable.core.page.TableDataInfo; |
| | | import org.ruoyi.flowable.factory.FlowServiceFactory; |
| | | import org.ruoyi.flowable.flow.FlowableUtils; |
| | | import org.ruoyi.flowable.utils.*; |
| | | import org.ruoyi.flowable.workflow.domain.WfDeployForm; |
| | | import org.ruoyi.flowable.workflow.domain.vo.*; |
| | | import org.ruoyi.flowable.workflow.mapper.WfDeployFormMapper; |
| | | import org.ruoyi.flowable.workflow.service.IWfProcessService; |
| | | import org.ruoyi.flowable.workflow.service.IWfTaskService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.bpmn.constants.BpmnXMLConstants; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.engine.history.HistoricActivityInstance; |
| | | import org.flowable.engine.history.HistoricActivityInstanceQuery; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstanceQuery; |
| | | 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.engine.task.Comment; |
| | | import org.flowable.identitylink.api.history.HistoricIdentityLink; |
| | | 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.variable.api.history.HistoricVariableInstance; |
| | | import org.ruoyi.system.domain.SysDept; |
| | | import org.ruoyi.system.domain.SysRole; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | import org.ruoyi.system.domain.vo.SysDeptVo; |
| | | import org.ruoyi.system.domain.vo.SysRoleVo; |
| | | import org.ruoyi.system.domain.vo.SysUserVo; |
| | | import org.ruoyi.system.service.ISysDeptService; |
| | | import org.ruoyi.system.service.ISysRoleService; |
| | | import org.ruoyi.system.service.ISysUserService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/24 18:57 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProcessService { |
| | | |
| | | private final IWfTaskService wfTaskService; |
| | | private final ISysUserService userService; |
| | | private final WfDeployFormMapper deployFormMapper; |
| | | private final ISysDeptService deptService; |
| | | private final ISysRoleService roleService; |
| | | @Autowired |
| | | private ISysUserService remoteUserService; |
| | | @Autowired |
| | | private ISysDeptService remoteDeptService; |
| | | /** |
| | | * æµç¨å®ä¹å表 |
| | | * |
| | | * @param pageQuery å页忰 |
| | | * @return æµç¨å®ä¹å页åè¡¨æ°æ® |
| | | */ |
| | | @Override |
| | | public TableDataInfo<WfDefinitionVo> selectPageStartProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | Page<WfDefinitionVo> page = new Page<>(); |
| | | // æµç¨å®ä¹åè¡¨æ°æ®æ¥è¯¢ |
| | | ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery() |
| | | .latestVersion() |
| | | .active() |
| | | .orderByProcessDefinitionKey() |
| | | .asc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(processDefinitionQuery, processQuery); |
| | | long pageTotal = processDefinitionQuery.count(); |
| | | if (pageTotal <= 0) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<ProcessDefinition> definitionList = processDefinitionQuery.listPage(offset, pageQuery.getPageSize()); |
| | | |
| | | List<WfDefinitionVo> definitionVoList = new ArrayList<>(); |
| | | for (ProcessDefinition processDefinition : definitionList) { |
| | | String deploymentId = processDefinition.getDeploymentId(); |
| | | Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult(); |
| | | WfDefinitionVo vo = new WfDefinitionVo(); |
| | | vo.setDefinitionId(processDefinition.getId()); |
| | | vo.setProcessKey(processDefinition.getKey()); |
| | | vo.setProcessName(processDefinition.getName()); |
| | | vo.setVersion(processDefinition.getVersion()); |
| | | vo.setDeploymentId(processDefinition.getDeploymentId()); |
| | | vo.setSuspended(processDefinition.isSuspended()); |
| | | // æµç¨å®ä¹æ¶é´ |
| | | vo.setCategory(deployment.getCategory()); |
| | | vo.setDeploymentTime(deployment.getDeploymentTime()); |
| | | definitionVoList.add(vo); |
| | | } |
| | | page.setRecords(definitionVoList); |
| | | page.setTotal(pageTotal); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfDefinitionVo> selectStartProcessList(ProcessQuery processQuery) { |
| | | // æµç¨å®ä¹åè¡¨æ°æ®æ¥è¯¢ |
| | | ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery() |
| | | .latestVersion() |
| | | .active() |
| | | .orderByProcessDefinitionKey() |
| | | .asc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(processDefinitionQuery, processQuery); |
| | | |
| | | List<ProcessDefinition> definitionList = processDefinitionQuery.list(); |
| | | |
| | | List<WfDefinitionVo> definitionVoList = new ArrayList<>(); |
| | | for (ProcessDefinition processDefinition : definitionList) { |
| | | String deploymentId = processDefinition.getDeploymentId(); |
| | | Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult(); |
| | | WfDefinitionVo vo = new WfDefinitionVo(); |
| | | vo.setDefinitionId(processDefinition.getId()); |
| | | vo.setProcessKey(processDefinition.getKey()); |
| | | vo.setProcessName(processDefinition.getName()); |
| | | vo.setVersion(processDefinition.getVersion()); |
| | | vo.setDeploymentId(processDefinition.getDeploymentId()); |
| | | vo.setSuspended(processDefinition.isSuspended()); |
| | | // æµç¨å®ä¹æ¶é´ |
| | | vo.setCategory(deployment.getCategory()); |
| | | vo.setDeploymentTime(deployment.getDeploymentTime()); |
| | | definitionVoList.add(vo); |
| | | } |
| | | return definitionVoList; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfTaskVo> selectPageOwnProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | Page<WfTaskVo> page = new Page<>(); |
| | | HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() |
| | | .startedBy(TaskUtils.getUserId()) |
| | | .orderByProcessInstanceStartTime() |
| | | .desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(historicProcessInstanceQuery, processQuery); |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery |
| | | .listPage(offset, pageQuery.getPageSize()); |
| | | page.setTotal(historicProcessInstanceQuery.count()); |
| | | List<WfTaskVo> taskVoList = new ArrayList<>(); |
| | | for (HistoricProcessInstance hisIns : historicProcessInstances) { |
| | | WfTaskVo taskVo = new WfTaskVo(); |
| | | // è·åæµç¨ç¶æ |
| | | HistoricVariableInstance processStatusVariable = historyService.createHistoricVariableInstanceQuery() |
| | | .processInstanceId(hisIns.getId()) |
| | | .variableName(ProcessConstants.PROCESS_STATUS_KEY) |
| | | .singleResult(); |
| | | String processStatus = null; |
| | | if (ObjectUtil.isNotNull(processStatusVariable)) { |
| | | processStatus = Convert.toStr(processStatusVariable.getValue()); |
| | | } |
| | | // å
¼å®¹æ§æµç¨ |
| | | if (processStatus == null) { |
| | | processStatus = ObjectUtil.isNull(hisIns.getEndTime()) ? ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus(); |
| | | } |
| | | taskVo.setProcessStatus(processStatus); |
| | | taskVo.setCreateTime(hisIns.getStartTime()); |
| | | taskVo.setFinishTime(hisIns.getEndTime()); |
| | | taskVo.setProcInsId(hisIns.getId()); |
| | | |
| | | // 计ç®èæ¶ |
| | | if (Objects.nonNull(hisIns.getEndTime())) { |
| | | taskVo.setDuration(DateUtils.getDatePoor(hisIns.getEndTime(), hisIns.getStartTime())); |
| | | } else { |
| | | taskVo.setDuration(DateUtils.getDatePoor(DateUtils.getNowDate(), hisIns.getStartTime())); |
| | | } |
| | | // æµç¨é¨ç½²å®ä¾ä¿¡æ¯ |
| | | Deployment deployment = repositoryService.createDeploymentQuery() |
| | | .deploymentId(hisIns.getDeploymentId()).singleResult(); |
| | | taskVo.setDeployId(hisIns.getDeploymentId()); |
| | | taskVo.setProcDefId(hisIns.getProcessDefinitionId()); |
| | | taskVo.setProcDefName(hisIns.getProcessDefinitionName()); |
| | | taskVo.setProcDefVersion(hisIns.getProcessDefinitionVersion()); |
| | | taskVo.setCategory(deployment.getCategory()); |
| | | // å½åæå¤æµç¨ |
| | | List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).includeIdentityLinks().list(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | taskVo.setTaskName(taskList.stream().map(Task::getName).filter(StringUtils::isNotEmpty).collect(Collectors.joining(","))); |
| | | } |
| | | taskVoList.add(taskVo); |
| | | } |
| | | page.setRecords(taskVoList); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfTaskVo> selectOwnProcessList(ProcessQuery processQuery) { |
| | | HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() |
| | | .startedBy(TaskUtils.getUserId()) |
| | | .orderByProcessInstanceStartTime() |
| | | .desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(historicProcessInstanceQuery, processQuery); |
| | | List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.list(); |
| | | List<WfTaskVo> taskVoList = new ArrayList<>(); |
| | | for (HistoricProcessInstance hisIns : historicProcessInstances) { |
| | | WfTaskVo taskVo = new WfTaskVo(); |
| | | taskVo.setCreateTime(hisIns.getStartTime()); |
| | | taskVo.setFinishTime(hisIns.getEndTime()); |
| | | taskVo.setProcInsId(hisIns.getId()); |
| | | |
| | | // 计ç®èæ¶ |
| | | if (Objects.nonNull(hisIns.getEndTime())) { |
| | | taskVo.setDuration(DateUtils.getDatePoor(hisIns.getEndTime(), hisIns.getStartTime())); |
| | | } else { |
| | | taskVo.setDuration(DateUtils.getDatePoor(DateUtils.getNowDate(), hisIns.getStartTime())); |
| | | } |
| | | // æµç¨é¨ç½²å®ä¾ä¿¡æ¯ |
| | | Deployment deployment = repositoryService.createDeploymentQuery() |
| | | .deploymentId(hisIns.getDeploymentId()).singleResult(); |
| | | taskVo.setDeployId(hisIns.getDeploymentId()); |
| | | taskVo.setProcDefId(hisIns.getProcessDefinitionId()); |
| | | taskVo.setProcDefName(hisIns.getProcessDefinitionName()); |
| | | taskVo.setProcDefVersion(hisIns.getProcessDefinitionVersion()); |
| | | taskVo.setCategory(deployment.getCategory()); |
| | | // å½åæå¤æµç¨ |
| | | List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).includeIdentityLinks().list(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | taskVo.setTaskName(taskList.stream().map(Task::getName).filter(StringUtils::isNotEmpty).collect(Collectors.joining(","))); |
| | | } |
| | | taskVoList.add(taskVo); |
| | | } |
| | | return taskVoList; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfTaskVo> selectPageTodoProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | Page<WfTaskVo> page = new Page<>(); |
| | | TaskQuery taskQuery = taskService.createTaskQuery() |
| | | .active() |
| | | .includeProcessVariables() |
| | | .taskCandidateOrAssigned(TaskUtils.getUserId()) |
| | | .taskCandidateGroupIn(TaskUtils.getCandidateGroup()) |
| | | .orderByTaskCreateTime().desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskQuery, processQuery); |
| | | page.setTotal(taskQuery.count()); |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<Task> taskList = taskQuery.listPage(offset, pageQuery.getPageSize()); |
| | | List<WfTaskVo> flowList = new ArrayList<>(); |
| | | for (Task task : taskList) { |
| | | WfTaskVo flowTask = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | flowTask.setTaskId(task.getId()); |
| | | flowTask.setTaskDefKey(task.getTaskDefinitionKey()); |
| | | flowTask.setCreateTime(task.getCreateTime()); |
| | | flowTask.setProcDefId(task.getProcessDefinitionId()); |
| | | 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()); |
| | | flowTask.setCategory(pd.getCategory()); |
| | | // æµç¨åèµ·äººä¿¡æ¯ |
| | | HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(task.getProcessInstanceId()) |
| | | .singleResult(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | flowTask.setStartUserId(userId); |
| | | flowTask.setStartUserName(nickName); |
| | | |
| | | // æµç¨åé |
| | | flowTask.setProcVars(task.getProcessVariables()); |
| | | |
| | | flowList.add(flowTask); |
| | | } |
| | | page.setRecords(flowList); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfTaskVo> selectTodoProcessList(ProcessQuery processQuery) { |
| | | TaskQuery taskQuery = taskService.createTaskQuery() |
| | | .active() |
| | | .includeProcessVariables() |
| | | .taskCandidateOrAssigned(TaskUtils.getUserId()) |
| | | .taskCandidateGroupIn(TaskUtils.getCandidateGroup()) |
| | | .orderByTaskCreateTime().desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskQuery, processQuery); |
| | | List<Task> taskList = taskQuery.list(); |
| | | List<WfTaskVo> taskVoList = new ArrayList<>(); |
| | | for (Task task : taskList) { |
| | | WfTaskVo taskVo = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | taskVo.setTaskId(task.getId()); |
| | | taskVo.setTaskDefKey(task.getTaskDefinitionKey()); |
| | | taskVo.setCreateTime(task.getCreateTime()); |
| | | taskVo.setProcDefId(task.getProcessDefinitionId()); |
| | | taskVo.setTaskName(task.getName()); |
| | | // æµç¨å®ä¹ä¿¡æ¯ |
| | | ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionId(task.getProcessDefinitionId()) |
| | | .singleResult(); |
| | | taskVo.setDeployId(pd.getDeploymentId()); |
| | | taskVo.setProcDefName(pd.getName()); |
| | | taskVo.setProcDefVersion(pd.getVersion()); |
| | | taskVo.setProcInsId(task.getProcessInstanceId()); |
| | | |
| | | // æµç¨åèµ·äººä¿¡æ¯ |
| | | HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(task.getProcessInstanceId()) |
| | | .singleResult(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | taskVo.setStartUserId(userId); |
| | | taskVo.setStartUserName(nickName); |
| | | |
| | | taskVoList.add(taskVo); |
| | | } |
| | | return taskVoList; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfTaskVo> selectPageClaimProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | Page<WfTaskVo> page = new Page<>(); |
| | | TaskQuery taskQuery = taskService.createTaskQuery() |
| | | .active() |
| | | .includeProcessVariables() |
| | | .taskCandidateUser(TaskUtils.getUserId()) |
| | | .taskCandidateGroupIn(TaskUtils.getCandidateGroup()) |
| | | .orderByTaskCreateTime().desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskQuery, processQuery); |
| | | page.setTotal(taskQuery.count()); |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<Task> taskList = taskQuery.listPage(offset, pageQuery.getPageSize()); |
| | | List<WfTaskVo> flowList = new ArrayList<>(); |
| | | for (Task task : taskList) { |
| | | WfTaskVo flowTask = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | flowTask.setTaskId(task.getId()); |
| | | flowTask.setTaskDefKey(task.getTaskDefinitionKey()); |
| | | flowTask.setCreateTime(task.getCreateTime()); |
| | | flowTask.setProcDefId(task.getProcessDefinitionId()); |
| | | 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(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | flowTask.setStartUserId(userId); |
| | | flowTask.setStartUserName(nickName); |
| | | |
| | | flowList.add(flowTask); |
| | | } |
| | | page.setRecords(flowList); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfTaskVo> selectClaimProcessList(ProcessQuery processQuery) { |
| | | TaskQuery taskQuery = taskService.createTaskQuery() |
| | | .active() |
| | | .includeProcessVariables() |
| | | .taskCandidateUser(TaskUtils.getUserId()) |
| | | .taskCandidateGroupIn(TaskUtils.getCandidateGroup()) |
| | | .orderByTaskCreateTime().desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskQuery, processQuery); |
| | | List<Task> taskList = taskQuery.list(); |
| | | List<WfTaskVo> flowList = new ArrayList<>(); |
| | | for (Task task : taskList) { |
| | | WfTaskVo flowTask = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | flowTask.setTaskId(task.getId()); |
| | | flowTask.setTaskDefKey(task.getTaskDefinitionKey()); |
| | | flowTask.setCreateTime(task.getCreateTime()); |
| | | flowTask.setProcDefId(task.getProcessDefinitionId()); |
| | | 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(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | flowTask.setStartUserId(userId); |
| | | flowTask.setStartUserName(nickName); |
| | | |
| | | flowList.add(flowTask); |
| | | } |
| | | return flowList; |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<WfTaskVo> selectPageFinishedProcessList(ProcessQuery processQuery, PageQuery pageQuery) { |
| | | Page<WfTaskVo> page = new Page<>(); |
| | | HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery() |
| | | .includeProcessVariables() |
| | | .finished() |
| | | .taskAssignee(TaskUtils.getUserId()) |
| | | .orderByHistoricTaskInstanceEndTime() |
| | | .desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskInstanceQuery, processQuery); |
| | | int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); |
| | | List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(offset, pageQuery.getPageSize()); |
| | | List<WfTaskVo> hisTaskList = new ArrayList<>(); |
| | | for (HistoricTaskInstance histTask : historicTaskInstanceList) { |
| | | WfTaskVo flowTask = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | flowTask.setTaskId(histTask.getId()); |
| | | // 审æ¹äººåä¿¡æ¯ |
| | | flowTask.setCreateTime(histTask.getCreateTime()); |
| | | flowTask.setFinishTime(histTask.getEndTime()); |
| | | flowTask.setDuration(DateUtil.formatBetween(histTask.getDurationInMillis(), BetweenFormatter.Level.SECOND)); |
| | | 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()); |
| | | flowTask.setCategory(pd.getCategory()); |
| | | // æµç¨åèµ·äººä¿¡æ¯ |
| | | HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(histTask.getProcessInstanceId()) |
| | | .singleResult(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | flowTask.setStartUserId(userId); |
| | | flowTask.setStartUserName(nickName); |
| | | |
| | | // æµç¨åé |
| | | flowTask.setProcVars(histTask.getProcessVariables()); |
| | | |
| | | hisTaskList.add(flowTask); |
| | | } |
| | | page.setTotal(taskInstanceQuery.count()); |
| | | page.setRecords(hisTaskList); |
| | | // Map<String, Object> result = new HashMap<>(); |
| | | // result.put("result",page); |
| | | // result.put("finished",true); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfTaskVo> selectFinishedProcessList(ProcessQuery processQuery) { |
| | | HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery() |
| | | .includeProcessVariables() |
| | | .finished() |
| | | .taskAssignee(TaskUtils.getUserId()) |
| | | .orderByHistoricTaskInstanceEndTime() |
| | | .desc(); |
| | | // æå»ºæç´¢æ¡ä»¶ |
| | | ProcessUtils.buildProcessSearch(taskInstanceQuery, processQuery); |
| | | List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.list(); |
| | | List<WfTaskVo> hisTaskList = new ArrayList<>(); |
| | | for (HistoricTaskInstance histTask : historicTaskInstanceList) { |
| | | WfTaskVo flowTask = new WfTaskVo(); |
| | | // å½åæµç¨ä¿¡æ¯ |
| | | flowTask.setTaskId(histTask.getId()); |
| | | // 审æ¹äººåä¿¡æ¯ |
| | | flowTask.setCreateTime(histTask.getCreateTime()); |
| | | flowTask.setFinishTime(histTask.getEndTime()); |
| | | flowTask.setDuration(DateUtil.formatBetween(histTask.getDurationInMillis(), BetweenFormatter.Level.SECOND)); |
| | | 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(); |
| | | Long userId = Long.parseLong(historicProcessInstance.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | flowTask.setStartUserId(userId); |
| | | flowTask.setStartUserName(nickName); |
| | | |
| | | // æµç¨åé |
| | | flowTask.setProcVars(histTask.getProcessVariables()); |
| | | |
| | | hisTaskList.add(flowTask); |
| | | } |
| | | return hisTaskList; |
| | | } |
| | | |
| | | @Override |
| | | public FormConf selectFormContent(String definitionId, String deployId, String procInsId) { |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionId); |
| | | if (ObjectUtil.isNull(bpmnModel)) { |
| | | throw new RuntimeException("è·åæµç¨è®¾è®¡å¤±è´¥ï¼"); |
| | | } |
| | | StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel); |
| | | WfDeployForm deployForm = deployFormMapper.selectOne(new LambdaQueryWrapper<WfDeployForm>() |
| | | .eq(WfDeployForm::getDeployId, deployId) |
| | | .eq(WfDeployForm::getFormKey, startEvent.getFormKey()) |
| | | .eq(WfDeployForm::getNodeKey, startEvent.getId())); |
| | | Map<String, Object> formModel = JsonUtils.parseObject(deployForm.getContent(), Map.class); |
| | | if (null == formModel || formModel.isEmpty()) { |
| | | throw new RuntimeException("è·åæµç¨è¡¨å失败ï¼"); |
| | | } |
| | | |
| | | |
| | | FormConf formConf = new FormConf(); |
| | | formConf.setFormBtns(false); |
| | | formConf.setFormModel(formModel); |
| | | if (ObjectUtil.isNotEmpty(procInsId)) { |
| | | // è·åæµç¨å®ä¾ |
| | | HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .includeProcessVariables() |
| | | .singleResult(); |
| | | formConf.setFormData(historicProcIns.getProcessVariables()); |
| | | } |
| | | return formConf; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æµç¨å®ä¹IDå¯å¨æµç¨å®ä¾ |
| | | * |
| | | * @param procDefId æµç¨å®ä¹Id |
| | | * @param variables æµç¨åé |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void startProcessByDefId(String procDefId, Map<String, Object> variables) { |
| | | try { |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionId(procDefId).singleResult(); |
| | | startProcess(processDefinition, variables); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException("æµç¨å¯å¨é误"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿DefinitionKeyå¯å¨æµç¨ |
| | | * @param procDefKey æµç¨å®ä¹Key |
| | | * @param variables æ©å±åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void startProcessByDefKey(String procDefKey, Map<String, Object> variables) { |
| | | try { |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionKey(procDefKey).latestVersion().singleResult(); |
| | | startProcess(processDefinition, variables); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException("æµç¨å¯å¨é误"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteProcessByIds(String[] instanceIds) { |
| | | List<String> ids = Arrays.asList(instanceIds); |
| | | // æ ¡éªæµç¨æ¯å¦ç»æ |
| | | long activeInsCount = runtimeService.createProcessInstanceQuery() |
| | | .processInstanceIds(new HashSet<>(ids)).active().count(); |
| | | if (activeInsCount > 0) { |
| | | throw new ServiceException("ä¸å
许å é¤è¿è¡ä¸çæµç¨å®ä¾"); |
| | | } |
| | | // å é¤å岿µç¨å®ä¾ |
| | | historyService.bulkDeleteHistoricProcessInstances(ids); |
| | | } |
| | | |
| | | /** |
| | | * 读åxmlæä»¶ |
| | | * @param processDefId æµç¨å®ä¹ID |
| | | */ |
| | | @Override |
| | | public String queryBpmnXmlById(String processDefId) { |
| | | InputStream inputStream = repositoryService.getProcessModel(processDefId); |
| | | try { |
| | | return IoUtil.readUtf8(inputStream); |
| | | } catch (IORuntimeException exception) { |
| | | throw new RuntimeException("å è½½xmlæä»¶å¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æµç¨è¯¦æ
ä¿¡æ¯ |
| | | * |
| | | * @param procInsId æµç¨å®ä¾ID |
| | | * @param taskId ä»»å¡ID |
| | | * @return |
| | | */ |
| | | @Override |
| | | public WfDetailVo queryProcessDetail(String procInsId, String taskId) { |
| | | WfDetailVo detailVo = new WfDetailVo(); |
| | | // è·åæµç¨å®ä¾ |
| | | HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .includeProcessVariables() |
| | | .singleResult(); |
| | | if (StringUtils.isNotBlank(taskId)) { |
| | | HistoricTaskInstance taskIns = historyService.createHistoricTaskInstanceQuery() |
| | | .taskId(taskId) |
| | | .includeIdentityLinks() |
| | | .includeProcessVariables() |
| | | .includeTaskLocalVariables() |
| | | .singleResult(); |
| | | if (taskIns == null) { |
| | | throw new ServiceException("没æå¯åççä»»å¡ï¼"); |
| | | } |
| | | detailVo.setTaskFormData(currTaskFormData(historicProcIns.getDeploymentId(), taskIns)); |
| | | } |
| | | // è·åBpmn模åä¿¡æ¯ |
| | | InputStream inputStream = repositoryService.getProcessModel(historicProcIns.getProcessDefinitionId()); |
| | | String bpmnXmlStr = StrUtil.utf8Str(IoUtil.readBytes(inputStream, false)); |
| | | BpmnModel bpmnModel = ModelUtils.getBpmnModel(bpmnXmlStr); |
| | | detailVo.setBpmnXml(bpmnXmlStr); |
| | | detailVo.setHistoryProcNodeList(historyProcNodeList(historicProcIns)); |
| | | detailVo.setProcessFormList(processFormList(bpmnModel, historicProcIns)); |
| | | detailVo.setFlowViewer(getFlowViewer(bpmnModel, procInsId)); |
| | | return detailVo; |
| | | } |
| | | |
| | | /** |
| | | * å¯å¨æµç¨å®ä¾ |
| | | */ |
| | | private void startProcess(ProcessDefinition procDef, Map<String, Object> variables) { |
| | | if (ObjectUtil.isNotNull(procDef) && procDef.isSuspended()) { |
| | | throw new ServiceException("æµç¨å·²è¢«æèµ·ï¼è¯·å
æ¿æ´»æµç¨"); |
| | | } |
| | | // 设置æµç¨å起人Idå°æµç¨ä¸ |
| | | String userIdStr = TaskUtils.getUserId(); |
| | | identityService.setAuthenticatedUserId(userIdStr); |
| | | variables.put(BpmnXMLConstants.ATTRIBUTE_EVENT_START_INITIATOR, userIdStr); |
| | | // 设置æµç¨ç¶æä¸ºè¿è¡ä¸ |
| | | variables.put(ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.RUNNING.getStatus()); |
| | | // åèµ·æµç¨å®ä¾ |
| | | ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDef.getId(), variables); |
| | | // 第ä¸ä¸ªç¨æ·ä»»å¡ä¸ºå起人ï¼åèªå¨å®æä»»å¡ |
| | | wfTaskService.startFirstTask(processInstance, variables); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åæµç¨åé |
| | | * |
| | | * @param taskId ä»»å¡ID |
| | | * @return æµç¨åé |
| | | */ |
| | | private Map<String, Object> getProcessVariables(String taskId) { |
| | | HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() |
| | | .includeProcessVariables() |
| | | .finished() |
| | | .taskId(taskId) |
| | | .singleResult(); |
| | | if (Objects.nonNull(historicTaskInstance)) { |
| | | return historicTaskInstance.getProcessVariables(); |
| | | } |
| | | return taskService.getVariables(taskId); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½å任塿µç¨è¡¨åä¿¡æ¯ |
| | | */ |
| | | private FormConf currTaskFormData(String deployId, HistoricTaskInstance taskIns) { |
| | | WfDeployFormVo deployFormVo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>() |
| | | .eq(WfDeployForm::getDeployId, deployId) |
| | | .eq(WfDeployForm::getFormKey, taskIns.getFormKey()) |
| | | .eq(WfDeployForm::getNodeKey, taskIns.getTaskDefinitionKey())); |
| | | if (ObjectUtil.isNotEmpty(deployFormVo)) { |
| | | FormConf currTaskFormData = JsonUtils.parseObject(deployFormVo.getContent(), FormConf.class); |
| | | if (null != currTaskFormData) { |
| | | currTaskFormData.setFormBtns(false); |
| | | ProcessFormUtils.fillFormData(currTaskFormData, taskIns.getTaskLocalVariables()); |
| | | return currTaskFormData; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åå岿µç¨è¡¨åä¿¡æ¯ |
| | | */ |
| | | private List<FormConf> processFormList(BpmnModel bpmnModel, HistoricProcessInstance historicProcIns) { |
| | | List<FormConf> procFormList = new ArrayList<>(); |
| | | |
| | | List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(historicProcIns.getId()).finished() |
| | | .activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_TASK_USER)) |
| | | .orderByHistoricActivityInstanceStartTime().asc() |
| | | .list(); |
| | | List<String> processFormKeys = new ArrayList<>(); |
| | | for (HistoricActivityInstance activityInstance : activityInstanceList) { |
| | | // è·åå½åèç¹æµç¨å
ç´ ä¿¡æ¯ |
| | | FlowElement flowElement = ModelUtils.getFlowElementById(bpmnModel, activityInstance.getActivityId()); |
| | | // è·åå½åèç¹è¡¨åKey |
| | | String formKey = ModelUtils.getFormKey(flowElement); |
| | | if (formKey == null) { |
| | | continue; |
| | | } |
| | | boolean localScope = Convert.toBool(ModelUtils.getElementAttributeValue(flowElement, ProcessConstants.PROCESS_FORM_LOCAL_SCOPE), false); |
| | | Map<String, Object> variables; |
| | | if (localScope) { |
| | | // æ¥è¯¢ä»»å¡èç¹åæ°ï¼å¹¶è½¬æ¢æMap |
| | | variables = historyService.createHistoricVariableInstanceQuery() |
| | | .processInstanceId(historicProcIns.getId()) |
| | | .taskId(activityInstance.getTaskId()) |
| | | .list() |
| | | .stream() |
| | | .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)); |
| | | } else { |
| | | if (processFormKeys.contains(formKey)) { |
| | | continue; |
| | | } |
| | | variables = historicProcIns.getProcessVariables(); |
| | | processFormKeys.add(formKey); |
| | | } |
| | | // éèç¹è¡¨åæ¤å¤æ¥è¯¢ç»æå¯è½æå¤æ¡ï¼åªè·åç¬¬ä¸æ¡ä¿¡æ¯ |
| | | List<WfDeployFormVo> formInfoList = deployFormMapper.selectVoList(new LambdaQueryWrapper<WfDeployForm>() |
| | | .eq(WfDeployForm::getDeployId, historicProcIns.getDeploymentId()) |
| | | .eq(WfDeployForm::getFormKey, formKey) |
| | | .eq(localScope, WfDeployForm::getNodeKey, flowElement.getId())); |
| | | |
| | | //@update by Brathï¼é¿å
空éå导è´çNULL空æé |
| | | WfDeployFormVo formInfo = formInfoList.stream().findFirst().orElse(null); |
| | | |
| | | if (ObjectUtil.isNotNull(formInfo)) { |
| | | // æ§æ°æ® formInfo.getFormName() 为 null |
| | | String formName = Optional.ofNullable(formInfo.getFormName()).orElse(StringUtils.EMPTY); |
| | | String title = localScope ? formName.concat("(" + flowElement.getName() + ")") : formName; |
| | | FormConf formConf = new FormConf(); |
| | | Map<String, Object> formModel = JsonUtils.parseObject(formInfo.getContent(), Map.class); |
| | | if (null != formModel && !formModel.isEmpty()) { |
| | | formConf.setTitle(title); |
| | | formConf.setDisabled(true); |
| | | formConf.setFormBtns(false); |
| | | formConf.setFormModel(formModel); |
| | | formConf.setFormData(variables); |
| | | procFormList.add(formConf); |
| | | } |
| | | } |
| | | } |
| | | return procFormList; |
| | | } |
| | | |
| | | @Deprecated |
| | | private void buildStartFormData(HistoricProcessInstance historicProcIns, Process process, String deployId, List<FormConf> procFormList) { |
| | | procFormList = procFormList == null ? new ArrayList<>() : procFormList; |
| | | HistoricActivityInstance startInstance = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(historicProcIns.getId()) |
| | | .activityId(historicProcIns.getStartActivityId()) |
| | | .singleResult(); |
| | | StartEvent startEvent = (StartEvent) process.getFlowElement(startInstance.getActivityId()); |
| | | WfDeployFormVo startFormInfo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>() |
| | | .eq(WfDeployForm::getDeployId, deployId) |
| | | .eq(WfDeployForm::getFormKey, startEvent.getFormKey()) |
| | | .eq(WfDeployForm::getNodeKey, startEvent.getId())); |
| | | if (ObjectUtil.isNotNull(startFormInfo)) { |
| | | FormConf formConf = JsonUtils.parseObject(startFormInfo.getContent(), FormConf.class); |
| | | if (null != formConf) { |
| | | formConf.setTitle(startEvent.getName()); |
| | | formConf.setDisabled(true); |
| | | formConf.setFormBtns(false); |
| | | ProcessFormUtils.fillFormData(formConf, historicProcIns.getProcessVariables()); |
| | | procFormList.add(formConf); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Deprecated |
| | | private void buildUserTaskFormData(String procInsId, String deployId, Process process, List<FormConf> procFormList) { |
| | | procFormList = procFormList == null ? new ArrayList<>() : procFormList; |
| | | List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(procInsId).finished() |
| | | .activityType(BpmnXMLConstants.ELEMENT_TASK_USER) |
| | | .orderByHistoricActivityInstanceStartTime().asc() |
| | | .list(); |
| | | for (HistoricActivityInstance instanceItem : activityInstanceList) { |
| | | UserTask userTask = (UserTask) process.getFlowElement(instanceItem.getActivityId(), true); |
| | | String formKey = userTask.getFormKey(); |
| | | if (formKey == null) { |
| | | continue; |
| | | } |
| | | // æ¥è¯¢ä»»å¡èç¹åæ°ï¼å¹¶è½¬æ¢æMap |
| | | Map<String, Object> variables = historyService.createHistoricVariableInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .taskId(instanceItem.getTaskId()) |
| | | .list() |
| | | .stream() |
| | | .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)); |
| | | WfDeployFormVo deployFormVo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>() |
| | | .eq(WfDeployForm::getDeployId, deployId) |
| | | .eq(WfDeployForm::getFormKey, formKey) |
| | | .eq(WfDeployForm::getNodeKey, userTask.getId())); |
| | | if (ObjectUtil.isNotNull(deployFormVo)) { |
| | | FormConf formConf = JsonUtils.parseObject(deployFormVo.getContent(), FormConf.class); |
| | | if (null != formConf) { |
| | | formConf.setTitle(userTask.getName()); |
| | | formConf.setDisabled(true); |
| | | formConf.setFormBtns(false); |
| | | ProcessFormUtils.fillFormData(formConf, variables); |
| | | procFormList.add(formConf); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·ååå²ä»»å¡ä¿¡æ¯å表 |
| | | */ |
| | | private List<WfProcNodeVo> historyProcNodeList(HistoricProcessInstance historicProcIns) { |
| | | String procInsId = historicProcIns.getId(); |
| | | List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_EVENT_END, BpmnXMLConstants.ELEMENT_TASK_USER)) |
| | | .orderByHistoricActivityInstanceStartTime().desc() |
| | | .orderByHistoricActivityInstanceEndTime().desc() |
| | | .list(); |
| | | |
| | | List<Comment> commentList = taskService.getProcessInstanceComments(procInsId); |
| | | |
| | | List<WfProcNodeVo> elementVoList = new ArrayList<>(); |
| | | for (HistoricActivityInstance activityInstance : historicActivityInstanceList) { |
| | | WfProcNodeVo elementVo = new WfProcNodeVo(); |
| | | elementVo.setProcDefId(activityInstance.getProcessDefinitionId()); |
| | | elementVo.setActivityId(activityInstance.getActivityId()); |
| | | elementVo.setActivityName(activityInstance.getActivityName()); |
| | | elementVo.setActivityType(activityInstance.getActivityType()); |
| | | elementVo.setCreateTime(activityInstance.getStartTime()); |
| | | elementVo.setEndTime(activityInstance.getEndTime()); |
| | | if (ObjectUtil.isNotNull(activityInstance.getDurationInMillis())) { |
| | | elementVo.setDuration(DateUtil.formatBetween(activityInstance.getDurationInMillis(), BetweenFormatter.Level.SECOND)); |
| | | } |
| | | |
| | | if (BpmnXMLConstants.ELEMENT_EVENT_START.equals(activityInstance.getActivityType())) { |
| | | if (ObjectUtil.isNotNull(historicProcIns)) { |
| | | Long userId = Long.parseLong(historicProcIns.getStartUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | if (nickName != null) { |
| | | elementVo.setAssigneeId(userId); |
| | | elementVo.setAssigneeName(nickName); |
| | | } |
| | | } |
| | | } else if (BpmnXMLConstants.ELEMENT_TASK_USER.equals(activityInstance.getActivityType())) { |
| | | if (StringUtils.isNotBlank(activityInstance.getAssignee())) { |
| | | Long userId = Long.parseLong(activityInstance.getAssignee()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | elementVo.setAssigneeId(userId); |
| | | elementVo.setAssigneeName(nickName); |
| | | } |
| | | // å±ç¤ºå®¡æ¹äººå |
| | | List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(activityInstance.getTaskId()); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | for (HistoricIdentityLink identityLink : linksForTask) { |
| | | if ("candidate".equals(identityLink.getType())) { |
| | | if (StringUtils.isNotBlank(identityLink.getUserId())) { |
| | | Long userId = Long.parseLong(identityLink.getUserId()); |
| | | String nickName = null; |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | stringBuilder.append(nickName).append(","); |
| | | } |
| | | if (StringUtils.isNotBlank(identityLink.getGroupId())) { |
| | | if (identityLink.getGroupId().startsWith(TaskConstants.ROLE_GROUP_PREFIX)) { |
| | | Long roleId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.ROLE_GROUP_PREFIX)); |
| | | //finish do æ¥è¯¢è§è²åç§° |
| | | SysRoleVo role=roleService.selectRoleById(roleId); |
| | | if (!ObjectUtil.isNull(role)) { |
| | | stringBuilder.append(role.getRoleName()).append(","); |
| | | } |
| | | } else if (identityLink.getGroupId().startsWith(TaskConstants.DEPT_GROUP_PREFIX)) { |
| | | Long deptId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.DEPT_GROUP_PREFIX)); |
| | | //finish do æ¥è¯¢é¨é¨åç§° |
| | | SysDeptVo deptR=deptService.selectDeptById(deptId); |
| | | if (!ObjectUtil.isNull(deptR) ) { |
| | | stringBuilder.append(deptR.getDeptName()).append(","); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (StringUtils.isNotBlank(stringBuilder)) { |
| | | elementVo.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1)); |
| | | } |
| | | // è·åæè§è¯è®ºå
容 |
| | | if (CollUtil.isNotEmpty(commentList)) { |
| | | List<Comment> comments = new ArrayList<>(); |
| | | for (Comment comment : commentList) { |
| | | |
| | | if (comment.getTaskId().equals(activityInstance.getTaskId())) { |
| | | comments.add(comment); |
| | | } |
| | | } |
| | | elementVo.setCommentList(comments); |
| | | } |
| | | } |
| | | elementVoList.add(elementVo); |
| | | } |
| | | return elementVoList; |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨æ§è¡è¿ç¨ |
| | | * |
| | | * @param procInsId |
| | | * @return |
| | | */ |
| | | private WfViewerVo getFlowViewer(BpmnModel bpmnModel, String procInsId) { |
| | | // æå»ºæ¥è¯¢æ¡ä»¶ |
| | | HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(procInsId); |
| | | List<HistoricActivityInstance> allActivityInstanceList = query.list(); |
| | | if (CollUtil.isEmpty(allActivityInstanceList)) { |
| | | return new WfViewerVo(); |
| | | } |
| | | // æ¥è¯¢ææå·²å®æçå
ç´ |
| | | List<HistoricActivityInstance> finishedElementList = allActivityInstanceList.stream() |
| | | .filter(item -> ObjectUtil.isNotNull(item.getEndTime())).collect(Collectors.toList()); |
| | | // ææå·²å®æçè¿çº¿ |
| | | Set<String> finishedSequenceFlowSet = new HashSet<>(); |
| | | // ææå·²å®æçä»»å¡èç¹ |
| | | Set<String> finishedTaskSet = new HashSet<>(); |
| | | finishedElementList.forEach(item -> { |
| | | if (BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW.equals(item.getActivityType())) { |
| | | finishedSequenceFlowSet.add(item.getActivityId()); |
| | | } else { |
| | | finishedTaskSet.add(item.getActivityId()); |
| | | } |
| | | }); |
| | | // æ¥è¯¢æææªç»æçèç¹ |
| | | Set<String> unfinishedTaskSet = allActivityInstanceList.stream() |
| | | .filter(item -> ObjectUtil.isNull(item.getEndTime())) |
| | | .map(HistoricActivityInstance::getActivityId) |
| | | .collect(Collectors.toSet()); |
| | | // DFS æ¥è¯¢æªéè¿çå
ç´ éå |
| | | Set<String> rejectedSet = FlowableUtils.dfsFindRejects(bpmnModel, unfinishedTaskSet, finishedSequenceFlowSet, finishedTaskSet); |
| | | return new WfViewerVo(finishedTaskSet, finishedSequenceFlowSet, unfinishedTaskSet, rejectedSet); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.flowable.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.domain.model.LoginUser; |
| | | import org.ruoyi.common.core.exception.ServiceException; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.flowable.common.constant.ProcessConstants; |
| | | import org.ruoyi.flowable.common.constant.TaskConstants; |
| | | import org.ruoyi.flowable.common.enums.FlowComment; |
| | | import org.ruoyi.flowable.common.enums.ProcessStatus; |
| | | import org.ruoyi.flowable.factory.FlowServiceFactory; |
| | | import org.ruoyi.flowable.flow.CustomProcessDiagramGenerator; |
| | | import org.ruoyi.flowable.flow.FlowableUtils; |
| | | import org.ruoyi.flowable.utils.ModelUtils; |
| | | import org.ruoyi.flowable.utils.TaskUtils; |
| | | import org.ruoyi.flowable.workflow.domain.bo.WfTaskBo; |
| | | import org.ruoyi.flowable.workflow.service.IWfCopyService; |
| | | import org.ruoyi.flowable.workflow.service.IWfTaskService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.flowable.bpmn.constants.BpmnXMLConstants; |
| | | 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.common.engine.impl.identity.Authentication; |
| | | import org.flowable.engine.ProcessEngineConfiguration; |
| | | import org.flowable.engine.history.HistoricActivityInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.flowable.engine.runtime.Execution; |
| | | import org.flowable.engine.runtime.ProcessInstance; |
| | | import org.flowable.image.ProcessDiagramGenerator; |
| | | import org.flowable.task.api.DelegationState; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | import org.ruoyi.system.domain.vo.SysUserVo; |
| | | import org.ruoyi.system.service.ISysUserService; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author KonBAI |
| | | * @createTime 2022/3/10 00:12 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | @Slf4j |
| | | public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskService { |
| | | |
| | | private final ISysUserService sysUserService; |
| | | |
| | | private final IWfCopyService copyService; |
| | | |
| | | /** |
| | | * å®æä»»å¡ |
| | | * |
| | | * @param taskBo 请æ±å®ä½åæ° |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void complete(WfTaskBo taskBo) { |
| | | Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult(); |
| | | if (Objects.isNull(task)) { |
| | | throw new ServiceException("ä»»å¡ä¸åå¨"); |
| | | } |
| | | // è·å bpmn 模å |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | if (DelegationState.PENDING.equals(task.getDelegationState())) { |
| | | taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.DELEGATE.getType(), taskBo.getComment()); |
| | | taskService.resolveTask(taskBo.getTaskId()); |
| | | } else { |
| | | taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.NORMAL.getType(), taskBo.getComment()); |
| | | taskService.setAssignee(taskBo.getTaskId(), TaskUtils.getUserId()); |
| | | if (ObjectUtil.isNotEmpty(taskBo.getVariables())) { |
| | | // è·å模åä¿¡æ¯ |
| | | String localScopeValue = ModelUtils.getUserTaskAttributeValue(bpmnModel, task.getTaskDefinitionKey(), ProcessConstants.PROCESS_FORM_LOCAL_SCOPE); |
| | | boolean localScope = Convert.toBool(localScopeValue, false); |
| | | taskService.complete(taskBo.getTaskId(), taskBo.getVariables(), localScope); |
| | | } else { |
| | | taskService.complete(taskBo.getTaskId()); |
| | | } |
| | | } |
| | | // 设置任å¡èç¹åç§° |
| | | taskBo.setTaskName(task.getName()); |
| | | // å¤çä¸ä¸çº§å®¡æ¹äºº |
| | | if (StringUtils.isNotBlank(taskBo.getNextUserIds())) { |
| | | this.assignNextUsers(bpmnModel, taskBo.getProcInsId(), taskBo.getNextUserIds()); |
| | | } |
| | | // å¤çæéç¨æ· |
| | | if (!copyService.makeCopy(taskBo)) { |
| | | throw new RuntimeException("æéä»»å¡å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æç»ä»»å¡ |
| | | * |
| | | * @param taskBo |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void taskReject(WfTaskBo taskBo) { |
| | | // å½åä»»å¡ task |
| | | Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult(); |
| | | if (ObjectUtil.isNull(task)) { |
| | | throw new RuntimeException("è·åä»»å¡ä¿¡æ¯å¼å¸¸ï¼"); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new RuntimeException("ä»»å¡å¤äºæèµ·ç¶æ"); |
| | | } |
| | | // è·åæµç¨å®ä¾ |
| | | ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() |
| | | .processInstanceId(taskBo.getProcInsId()) |
| | | .singleResult(); |
| | | if (processInstance == null) { |
| | | throw new RuntimeException("æµç¨å®ä¾ä¸åå¨ï¼è¯·ç¡®è®¤ï¼"); |
| | | } |
| | | // è·åæµç¨å®ä¹ä¿¡æ¯ |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionId(task.getProcessDefinitionId()) |
| | | .singleResult(); |
| | | |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | // æ·»å å®¡æ¹æè§ |
| | | taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.REJECT.getType(), taskBo.getComment()); |
| | | // 设置æµç¨ç¶æä¸ºå·²ç»ç» |
| | | runtimeService.setVariable(processInstance.getId(), ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.TERMINATED.getStatus()); |
| | | // è·åææèç¹ä¿¡æ¯ |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); |
| | | EndEvent endEvent = ModelUtils.getEndEvent(bpmnModel); |
| | | // ç»æ¢æµç¨ |
| | | List<Execution> executions = runtimeService.createExecutionQuery().parentId(task.getProcessInstanceId()).list(); |
| | | List<String> executionIds = executions.stream().map(Execution::getId).collect(Collectors.toList()); |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .processInstanceId(task.getProcessInstanceId()) |
| | | .moveExecutionsToSingleActivityId(executionIds, endEvent.getId()) |
| | | .changeState(); |
| | | // å¤çæéç¨æ· |
| | | if (!copyService.makeCopy(taskBo)) { |
| | | throw new RuntimeException("æéä»»å¡å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éåä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void taskReturn(WfTaskBo bo) { |
| | | // å½åä»»å¡ task |
| | | Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult(); |
| | | if (ObjectUtil.isNull(task)) { |
| | | throw new RuntimeException("è·åä»»å¡ä¿¡æ¯å¼å¸¸ï¼"); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new RuntimeException("ä»»å¡å¤äºæèµ·ç¶æ"); |
| | | } |
| | | // è·åæµç¨å®ä¹ä¿¡æ¯ |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); |
| | | // è·åæµç¨æ¨¡åä¿¡æ¯ |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); |
| | | // è·åå½åä»»å¡èç¹å
ç´ |
| | | FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); |
| | | // è·å跳转çèç¹å
ç´ |
| | | FlowElement target = ModelUtils.getFlowElementById(bpmnModel, bo.getTargetKey()); |
| | | // ä»å½åèç¹ååæ«æï¼å¤æå½åèç¹ä¸ç®æ èç¹æ¯å¦å±äºä¸²è¡ï¼è¥ç®æ èç¹æ¯å¨å¹¶è¡ç½å
³ä¸æéåä¸è·¯çº¿ä¸ï¼ä¸å¯è·³è½¬ |
| | | boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>()); |
| | | if (!isSequential) { |
| | | throw new RuntimeException("å½åèç¹ç¸å¯¹äºç®æ èç¹ï¼ä¸å±äºä¸²è¡å
³ç³»ï¼æ æ³åé"); |
| | | } |
| | | |
| | | // è·åæææ£å¸¸è¿è¡çä»»å¡èç¹ Keyï¼è¿äºä»»å¡ä¸è½ç´æ¥ä½¿ç¨ï¼éè¦æ¾åºå
¶ä¸éè¦æ¤åçä»»å¡ |
| | | List<Task> runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); |
| | | List<String> runTaskKeyList = new ArrayList<>(); |
| | | runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey())); |
| | | // ééåä»»å¡å表 |
| | | List<String> currentIds = new ArrayList<>(); |
| | | // éè¿ç¶çº§ç½å
³çåºå£è¿çº¿ï¼ç»å runTaskList æ¯å¯¹ï¼è·åéè¦æ¤åçä»»å¡ |
| | | List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(target, runTaskKeyList, null, null); |
| | | currentUserTaskList.forEach(item -> currentIds.add(item.getId())); |
| | | |
| | | // 循ç¯è·åé£äºéè¦è¢«æ¤åçèç¹çIDï¼ç¨æ¥è®¾ç½®é©³ååå |
| | | List<String> currentTaskIds = new ArrayList<>(); |
| | | currentIds.forEach(currentId -> runTaskList.forEach(runTask -> { |
| | | if (currentId.equals(runTask.getTaskDefinitionKey())) { |
| | | currentTaskIds.add(runTask.getId()); |
| | | } |
| | | })); |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | // 设置åéæè§ |
| | | for (String currentTaskId : currentTaskIds) { |
| | | taskService.addComment(currentTaskId, task.getProcessInstanceId(), FlowComment.REBACK.getType(), bo.getComment()); |
| | | } |
| | | |
| | | try { |
| | | // 1 对 1 æ å¤ å¯¹ 1 æ
åµï¼currentIds å½åè¦è·³è½¬çèç¹å表(1æå¤)ï¼targetKey 跳转å°çèç¹(1) |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .processInstanceId(task.getProcessInstanceId()) |
| | | .moveActivityIdsToSingleActivityId(currentIds, bo.getTargetKey()).changeState(); |
| | | } catch (FlowableObjectNotFoundException e) { |
| | | throw new RuntimeException("æªæ¾å°æµç¨å®ä¾ï¼æµç¨å¯è½å·²åçåå"); |
| | | } catch (FlowableException e) { |
| | | throw new RuntimeException("æ æ³åæ¶æå¼å§æ´»å¨"); |
| | | } |
| | | // 设置任å¡èç¹åç§° |
| | | bo.setTaskName(task.getName()); |
| | | // å¤çæéç¨æ· |
| | | if (!copyService.makeCopy(bo)) { |
| | | throw new RuntimeException("æéä»»å¡å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åææå¯åéçèç¹ |
| | | * |
| | | * @param bo |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<FlowElement> findReturnTaskList(WfTaskBo bo) { |
| | | // å½åä»»å¡ task |
| | | Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult(); |
| | | // è·åæµç¨å®ä¹ä¿¡æ¯ |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); |
| | | // è·åæµç¨æ¨¡åä¿¡æ¯ |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); |
| | | // æ¥è¯¢åå²èç¹å®ä¾ |
| | | List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(task.getProcessInstanceId()) |
| | | .activityType(BpmnXMLConstants.ELEMENT_TASK_USER) |
| | | .finished() |
| | | .orderByHistoricActivityInstanceEndTime().asc() |
| | | .list(); |
| | | List<String> activityIdList = activityInstanceList.stream() |
| | | .map(HistoricActivityInstance::getActivityId) |
| | | .filter(activityId -> !StringUtils.equals(activityId, task.getTaskDefinitionKey())) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | // è·åå½åä»»å¡èç¹å
ç´ |
| | | FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); |
| | | List<FlowElement> elementList = new ArrayList<>(); |
| | | for (String activityId : activityIdList) { |
| | | FlowElement target = ModelUtils.getFlowElementById(bpmnModel, activityId); |
| | | boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>()); |
| | | if (isSequential) { |
| | | elementList.add(target); |
| | | } |
| | | } |
| | | return elementList; |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | public void deleteTask(WfTaskBo bo) { |
| | | // todo å¾
确认å é¤ä»»å¡æ¯ç©çå é¤ä»»å¡ è¿æ¯é»è¾å é¤ï¼è®©è¿ä¸ªä»»å¡ç´æ¥éè¿ï¼ |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | taskService.deleteTask(bo.getTaskId(), bo.getComment()); |
| | | } |
| | | |
| | | /** |
| | | * 认é¢/ç¾æ¶ä»»å¡ |
| | | * |
| | | * @param taskBo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void claim(WfTaskBo taskBo) { |
| | | Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult(); |
| | | if (Objects.isNull(task)) { |
| | | throw new ServiceException("ä»»å¡ä¸åå¨"); |
| | | } |
| | | taskService.claim(taskBo.getTaskId(), TaskUtils.getUserId()); |
| | | } |
| | | |
| | | /** |
| | | * åæ¶è®¤é¢/ç¾æ¶ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void unClaim(WfTaskBo bo) { |
| | | taskService.unclaim(bo.getTaskId()); |
| | | } |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void delegateTask(WfTaskBo bo) { |
| | | // å½åä»»å¡ task |
| | | Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException("è·åä»»å¡å¤±è´¥ï¼"); |
| | | } |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | String currentNickname = null; |
| | | if (ObjectUtil.isNotNull(loginUser)){ |
| | | currentNickname=loginUser.getNickName(); |
| | | } |
| | | StringBuilder commentBuilder = new StringBuilder(currentNickname) |
| | | .append("->"); |
| | | |
| | | String nickName = null; |
| | | SysUserVo user = sysUserService.selectUserById(Long.parseLong(bo.getUserId())); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | if (StringUtils.isNotBlank(nickName)) { |
| | | commentBuilder.append(nickName); |
| | | } else { |
| | | commentBuilder.append(bo.getUserId()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getComment())) { |
| | | commentBuilder.append(": ").append(bo.getComment()); |
| | | } |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | // æ·»å å®¡æ¹æè§ |
| | | taskService.addComment(bo.getTaskId(), task.getProcessInstanceId(), FlowComment.DELEGATE.getType(), commentBuilder.toString()); |
| | | // 设置åç人为å½åç»å½äºº |
| | | taskService.setOwner(bo.getTaskId(), TaskUtils.getUserId()); |
| | | // æ§è¡å§æ´¾ |
| | | taskService.delegateTask(bo.getTaskId(), bo.getUserId()); |
| | | // 设置任å¡èç¹åç§° |
| | | bo.setTaskName(task.getName()); |
| | | // å¤çæéç¨æ· |
| | | if (!copyService.makeCopy(bo)) { |
| | | throw new RuntimeException("æéä»»å¡å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * |
| | | * @param bo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void transferTask(WfTaskBo bo) { |
| | | // å½åä»»å¡ task |
| | | Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException("è·åä»»å¡å¤±è´¥ï¼"); |
| | | } |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | String currentNickname = null; |
| | | if (ObjectUtil.isNotNull(loginUser)){ |
| | | currentNickname=loginUser.getNickName(); |
| | | } |
| | | StringBuilder commentBuilder = new StringBuilder(currentNickname) |
| | | .append("->"); |
| | | |
| | | String nickName = null; |
| | | SysUserVo user = sysUserService.selectUserById(Long.parseLong(bo.getUserId())); |
| | | if(!ObjectUtil.isNull(user)) { |
| | | nickName=user.getNickName(); |
| | | } |
| | | if (StringUtils.isNotBlank(nickName)) { |
| | | commentBuilder.append(nickName); |
| | | } else { |
| | | commentBuilder.append(bo.getUserId()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getComment())) { |
| | | commentBuilder.append(": ").append(bo.getComment()); |
| | | } |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | // æ·»å å®¡æ¹æè§ |
| | | taskService.addComment(bo.getTaskId(), task.getProcessInstanceId(), FlowComment.TRANSFER.getType(), commentBuilder.toString()); |
| | | // è®¾ç½®æ¥æè
为å½åç»å½äºº |
| | | taskService.setOwner(bo.getTaskId(), TaskUtils.getUserId()); |
| | | // 转åä»»å¡ |
| | | taskService.setAssignee(bo.getTaskId(), bo.getUserId()); |
| | | // 设置任å¡èç¹åç§° |
| | | bo.setTaskName(task.getName()); |
| | | // å¤çæéç¨æ· |
| | | if (!copyService.makeCopy(bo)) { |
| | | throw new RuntimeException("æéä»»å¡å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åæ¶ç³è¯· |
| | | * |
| | | * @param bo |
| | | * @return |
| | | */ |
| | | @Override |
| | | public void stopProcess(WfTaskBo bo) { |
| | | List<Task> taskList = taskService.createTaskQuery().processInstanceId(bo.getProcInsId()).list(); |
| | | if (CollectionUtils.isEmpty(taskList)) { |
| | | throw new RuntimeException("æµç¨æªå¯å¨æå·²æ§è¡å®æï¼åæ¶ç³è¯·å¤±è´¥"); |
| | | } |
| | | |
| | | ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() |
| | | .processInstanceId(bo.getProcInsId()).singleResult(); |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); |
| | | if (Objects.nonNull(bpmnModel)) { |
| | | Process process = bpmnModel.getMainProcess(); |
| | | List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false); |
| | | if (CollectionUtils.isNotEmpty(endNodes)) { |
| | | Authentication.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | runtimeService.setVariable(processInstance.getId(), ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.CANCELED.getStatus()); |
| | | for (Task task : taskList) { |
| | | taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(), "åæ¶æµç¨"); |
| | | } |
| | | // è·åå½åæµç¨æåä¸ä¸ªèç¹ |
| | | String endId = endNodes.get(0).getId(); |
| | | List<Execution> executions = runtimeService.createExecutionQuery() |
| | | .parentId(processInstance.getProcessInstanceId()).list(); |
| | | List<String> executionIds = new ArrayList<>(); |
| | | executions.forEach(execution -> executionIds.add(execution.getId())); |
| | | // åæ´æµç¨ä¸ºå·²ç»æç¶æ |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .moveExecutionsToSingleActivityId(executionIds, endId).changeState(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¤åæµç¨ |
| | | * |
| | | * @param taskBo 请æ±å®ä½åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void revokeProcess(WfTaskBo taskBo) { |
| | | String procInsId = taskBo.getProcInsId(); |
| | | String taskId = taskBo.getTaskId(); |
| | | // æ ¡éªæµç¨æ¯å¦ç»æ |
| | | ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .active() |
| | | .singleResult(); |
| | | if(ObjectUtil.isNull(processInstance)) { |
| | | throw new RuntimeException("æµç¨å·²ç»ææå·²æèµ·ï¼æ æ³æ§è¡æ¤åæä½"); |
| | | } |
| | | // è·åå¾
æ¤åä»»å¡å®ä¾ |
| | | HistoricTaskInstance currTaskIns = historyService.createHistoricTaskInstanceQuery() |
| | | .taskId(taskId) |
| | | .taskAssignee(TaskUtils.getUserId()) |
| | | .singleResult(); |
| | | if (ObjectUtil.isNull(currTaskIns)) { |
| | | throw new RuntimeException("å½åä»»å¡ä¸åå¨ï¼æ æ³æ§è¡æ¤åæä½"); |
| | | } |
| | | // è·å bpmn 模å |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(currTaskIns.getProcessDefinitionId()); |
| | | UserTask currUserTask = ModelUtils.getUserTaskByKey(bpmnModel, currTaskIns.getTaskDefinitionKey()); |
| | | // æ¥æ¾ä¸ä¸çº§ç¨æ·ä»»å¡å表 |
| | | List<UserTask> nextUserTaskList = ModelUtils.findNextUserTasks(currUserTask); |
| | | List<String> nextUserTaskKeys = nextUserTaskList.stream().map(UserTask::getId).collect(Collectors.toList()); |
| | | |
| | | // è·åå½åèç¹ä¹åå·²å®æçæµç¨åå²èç¹ |
| | | List<HistoricTaskInstance> finishedTaskInsList = historyService.createHistoricTaskInstanceQuery() |
| | | .processInstanceId(procInsId) |
| | | .taskCreatedAfter(currTaskIns.getEndTime()) |
| | | .finished() |
| | | .list(); |
| | | for (HistoricTaskInstance finishedTaskInstance : finishedTaskInsList) { |
| | | // æ£æ¥å·²å®ææµç¨åå²èç¹æ¯å¦åå¨ä¸ä¸çº§ä¸ |
| | | if (CollUtil.contains(nextUserTaskKeys, finishedTaskInstance.getTaskDefinitionKey())) { |
| | | throw new RuntimeException("ä¸ä¸æµç¨å·²å¤çï¼æ æ³æ§è¡æ¤åæä½"); |
| | | } |
| | | } |
| | | // è·åæææ¿æ´»çä»»å¡èç¹ï¼æ¾å°éè¦æ¤åçä»»å¡ |
| | | List<Task> activateTaskList = taskService.createTaskQuery().processInstanceId(procInsId).list(); |
| | | List<String> revokeExecutionIds = new ArrayList<>(); |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | for (Task task : activateTaskList) { |
| | | // æ£æ¥æ¿æ´»çä»»å¡èç¹æ¯å¦åå¨ä¸ä¸çº§ä¸ï¼å¦æåå¨ï¼åå å
¥å°éè¦æ¤åçèç¹ |
| | | if (CollUtil.contains(nextUserTaskKeys, task.getTaskDefinitionKey())) { |
| | | // æ·»å æ¤å审æ¹ä¿¡æ¯ |
| | | taskService.setAssignee(task.getId(), TaskUtils.getUserId()); |
| | | |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | String currentNickname = null; |
| | | if (ObjectUtil.isNotNull(loginUser)){ |
| | | currentNickname=loginUser.getNickName(); |
| | | } |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), FlowComment.REVOKE.getType(), currentNickname + "æ¤åæµç¨å®¡æ¹"); |
| | | revokeExecutionIds.add(task.getExecutionId()); |
| | | } |
| | | } |
| | | try { |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .processInstanceId(procInsId) |
| | | .moveExecutionsToSingleActivityId(revokeExecutionIds, currTaskIns.getTaskDefinitionKey()).changeState(); |
| | | } catch (FlowableObjectNotFoundException e) { |
| | | throw new RuntimeException("æªæ¾å°æµç¨å®ä¾ï¼æµç¨å¯è½å·²åçåå"); |
| | | } catch (FlowableException e) { |
| | | throw new RuntimeException("æ§è¡æ¤åæä½å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨è¿ç¨å¾ |
| | | * |
| | | * @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<HistoricActivityInstance> highLightedFlowList = historyService.createHistoricActivityInstanceQuery() |
| | | .processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list(); |
| | | |
| | | List<String> highLightedFlows = new ArrayList<>(); |
| | | List<String> 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(); |
| | | return diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(), |
| | | configuration.getLabelFontName(), configuration.getAnnotationFontName(), configuration.getClassLoader(), 1.0, true); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨åé |
| | | * |
| | | * @param taskId ä»»å¡ID |
| | | * @return æµç¨åé |
| | | */ |
| | | @Override |
| | | public Map<String, Object> getProcessVariables(String taskId) { |
| | | HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() |
| | | .includeProcessVariables() |
| | | .finished() |
| | | .taskId(taskId) |
| | | .singleResult(); |
| | | if (Objects.nonNull(historicTaskInstance)) { |
| | | return historicTaskInstance.getProcessVariables(); |
| | | } |
| | | return taskService.getVariables(taskId); |
| | | } |
| | | |
| | | /** |
| | | * å¯å¨ç¬¬ä¸ä¸ªä»»å¡ |
| | | * @param processInstance æµç¨å®ä¾ |
| | | * @param variables æµç¨åæ° |
| | | */ |
| | | @Override |
| | | public void startFirstTask(ProcessInstance processInstance, Map<String, Object> variables) { |
| | | // è¥ç¬¬ä¸ä¸ªç¨æ·ä»»å¡ä¸ºå起人ï¼åèªå¨å®æä»»å¡ |
| | | List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list(); |
| | | if (CollUtil.isNotEmpty(tasks)) { |
| | | String userIdStr = (String) variables.get(TaskConstants.PROCESS_INITIATOR); |
| | | identityService.setAuthenticatedUserId(TaskUtils.getUserId()); |
| | | // è·åå½åçç¨æ· |
| | | LoginUser loginUser = LoginHelper.getLoginUser(); |
| | | String currentNickname = null; |
| | | if (ObjectUtil.isNotNull(loginUser)){ |
| | | currentNickname=loginUser.getNickName(); |
| | | } |
| | | for (Task task : tasks) { |
| | | if (StrUtil.equals(task.getAssignee(), userIdStr)) { |
| | | taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), currentNickname+ "åèµ·æµç¨ç³è¯·"); |
| | | taskService.complete(task.getId(), variables); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ææ´¾ä¸ä¸ä»»å¡å®¡æ¹äºº |
| | | * @param bpmnModel bpmn模å |
| | | * @param processInsId æµç¨å®ä¾id |
| | | * @param userIds ç¨æ·ids |
| | | */ |
| | | private void assignNextUsers(BpmnModel bpmnModel, String processInsId, String userIds) { |
| | | // è·åææèç¹ä¿¡æ¯ |
| | | List<Task> list = taskService.createTaskQuery() |
| | | .processInstanceId(processInsId) |
| | | .list(); |
| | | if (list.size() == 0) { |
| | | return; |
| | | } |
| | | Queue<String> assignIds = CollUtil.newLinkedList(userIds.split(",")); |
| | | if (list.size() == assignIds.size()) { |
| | | for (Task task : list) { |
| | | taskService.setAssignee(task.getId(), assignIds.poll()); |
| | | } |
| | | return; |
| | | } |
| | | // ä¼å
å¤çéå¤å®ä¾ä»»å¡ |
| | | Iterator<Task> iterator = list.iterator(); |
| | | while (iterator.hasNext()) { |
| | | Task task = iterator.next(); |
| | | if (!ModelUtils.isMultiInstance(bpmnModel, task.getTaskDefinitionKey())) { |
| | | if (!assignIds.isEmpty()) { |
| | | taskService.setAssignee(task.getId(), assignIds.poll()); |
| | | } |
| | | iterator.remove(); |
| | | } |
| | | } |
| | | // è¥åå¨å¤å®ä¾ä»»å¡ï¼åè¿è¡å¨æå åç¾ |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | if (assignIds.isEmpty()) { |
| | | // 卿åç¾ |
| | | for (Task task : list) { |
| | | runtimeService.deleteMultiInstanceExecution(task.getExecutionId(), true); |
| | | } |
| | | } else { |
| | | // 卿å ç¾ |
| | | for (String assignId : assignIds) { |
| | | Map<String, Object> assignVariables = Collections.singletonMap(BpmnXMLConstants.ATTRIBUTE_TASK_USER_ASSIGNEE, assignId); |
| | | runtimeService.addMultiInstanceExecution(list.get(0).getTaskDefinitionKey(), list.get(0).getProcessInstanceId(), assignVariables); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | Spring Boot Version: ${spring-boot.version} |
| | | Spring Application Name: ${spring.application.name} |
| | | ââ ââââ ââ ââ ââ |
| | | ââ ââââ ââââ âââ âââ âââ |
| | | ââââââ ââ ââ ââââââ ââââ ââ ââ ââââââ âââ ââââââ âââ ââ ââââââ âââ âââ âââââ |
| | | ââââââââââ âââ ââââââââ âââââ âââ âââââââââââ âââ ââââââââââââ â âââ ââââââââ âââââââ âââ âââââââ |
| | | âââ â âââ ââââââ âââ âââ ââââââââ âââ ââââââ âââ âââ ââââââ âââââââ ââââââââ âââââââââââ |
| | | âââ âââ ââââââ âââ ââ âââ âââ ââââââ âââ ââââââââââ ââââââââ âââ âââ ââââââââââ |
| | | ââââ ââââââââââââââââ ââ âââ âââ âââââââââââ ââââ ââââââââââââââââââââââ âââââââââââ |
| | | âââ ââââââ ââââââ ââ ââ ââ âââ ââââââ âââ âââ ââââââââ âââââ âââ ââââââ |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | # Tomcat |
| | | server: |
| | | port: 9308 |
| | | |
| | | # Spring |
| | | spring: |
| | | main: |
| | | lazy-initialization: true #é»è®¤false å
³é |
| | | application: |
| | | # åºç¨åç§° |
| | | name: ruoyi-flowable |
| | | profiles: |
| | | # ç¯å¢é
ç½® |
| | | active: dev |
| | | cloud: |
| | | nacos: |
| | | discovery: |
| | | # æå¡æ³¨åå°å |
| | | server-addr: 127.0.0.1:8848 |
| | | config: |
| | | # é
ç½®ä¸å¿å°å |
| | | server-addr: 127.0.0.1:8848 |
| | | # é
ç½®æä»¶æ ¼å¼ |
| | | file-extension: yml |
| | | # å
±äº«é
ç½® |
| | | shared-configs: |
| | | - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <configuration scan="true" scanPeriod="60 seconds" debug="false"> |
| | | <!-- æ¥å¿åæ¾è·¯å¾ --> |
| | | <property name="log.path" value="logs/ruoyi-flowable" /> |
| | | <!-- æ¥å¿è¾åºæ ¼å¼ --> |
| | | <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> |
| | | |
| | | <!-- æ§å¶å°è¾åº --> |
| | | <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- ç³»ç»æ¥å¿è¾åº --> |
| | | <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <file>${log.path}/info.log</file> |
| | | <!-- å¾ªç¯æ¿çï¼åºäºæ¶é´å建æ¥å¿æä»¶ --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <!-- æ¥å¿æä»¶åæ ¼å¼ --> |
| | | <fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern> |
| | | <!-- æ¥å¿æå¤§çåå² 60天 --> |
| | | <maxHistory>60</maxHistory> |
| | | </rollingPolicy> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | </encoder> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <!-- è¿æ»¤ççº§å« --> |
| | | <level>INFO</level> |
| | | <!-- å¹é
æ¶çæä½ï¼æ¥æ¶ï¼è®°å½ï¼ --> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <!-- ä¸å¹é
æ¶çæä½ï¼æç»ï¼ä¸è®°å½ï¼ --> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <file>${log.path}/error.log</file> |
| | | <!-- å¾ªç¯æ¿çï¼åºäºæ¶é´å建æ¥å¿æä»¶ --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <!-- æ¥å¿æä»¶åæ ¼å¼ --> |
| | | <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern> |
| | | <!-- æ¥å¿æå¤§çåå² 60天 --> |
| | | <maxHistory>60</maxHistory> |
| | | </rollingPolicy> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | </encoder> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <!-- è¿æ»¤ççº§å« --> |
| | | <level>ERROR</level> |
| | | <!-- å¹é
æ¶çæä½ï¼æ¥æ¶ï¼è®°å½ï¼ --> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <!-- ä¸å¹é
æ¶çæä½ï¼æç»ï¼ä¸è®°å½ï¼ --> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <!-- Console Appender --> |
| | | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- MyBatis-Plus Logger Configuration --> |
| | | <logger name="com.baomidou.mybatisplus" level="DEBUG"/> |
| | | |
| | | <!-- ç³»ç»æ¨¡åæ¥å¿çº§å«æ§å¶ --> |
| | | <logger name="com.ruoyi" level="info" /> |
| | | <!-- Springæ¥å¿çº§å«æ§å¶ --> |
| | | <logger name="org.springframework" level="warn" /> |
| | | |
| | | <root level="info"> |
| | | <appender-ref ref="console" /> |
| | | </root> |
| | | |
| | | <!--ç³»ç»æä½æ¥å¿--> |
| | | <root level="info"> |
| | | <appender-ref ref="file_info" /> |
| | | <appender-ref ref="file_error" /> |
| | | </root> |
| | | </configuration> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="org.ruoyi.flowable.workflow.mapper.WfCategoryMapper"> |
| | | |
| | | <resultMap type="org.ruoyi.flowable.workflow.domain.WfCategory" id="FlowCategoryResult"> |
| | | <result property="categoryId" column="category_id"/> |
| | | <result property="categoryName" column="category_name"/> |
| | | <result property="code" column="code"/> |
| | | <result property="createBy" column="create_by"/> |
| | | <result property="createTime" column="create_time"/> |
| | | <result property="updateBy" column="update_by"/> |
| | | <result property="updateTime" column="update_time"/> |
| | | <result property="remark" column="remark"/> |
| | | <result property="delFlag" column="del_flag"/> |
| | | </resultMap> |
| | | |
| | | </mapper> |