!538 ♥️发布 5.2.0-BETA 公测版本
Merge pull request !538 from 疯狂的狮子Li/dev
已添加162个文件
已重命名3个文件
已删除25个文件
已修改170个文件
| | |
| | | <configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
| | | <deployment type="dockerfile"> |
| | | <settings> |
| | | <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.1.2" /> |
| | | <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.2.0" /> |
| | | <option name="buildOnly" value="true" /> |
| | | <option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> |
| | | </settings> |
| | |
| | | <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
| | | <deployment type="dockerfile"> |
| | | <settings> |
| | | <option name="imageTag" value="ruoyi/ruoyi-server:5.1.2" /> |
| | | <option name="imageTag" value="ruoyi/ruoyi-server:5.2.0" /> |
| | | <option name="buildOnly" value="true" /> |
| | | <option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> |
| | | </settings> |
ÎļþÃû´Ó .run/ruoyi-powerjob-server.run.xml ÐÞ¸Ä |
| | |
| | | <component name="ProjectRunConfigurationManager"> |
| | | <configuration default="false" name="ruoyi-powerjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
| | | <configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
| | | <deployment type="dockerfile"> |
| | | <settings> |
| | | <option name="imageTag" value="ruoyi/ruoyi-powerjob-server:5.1.2" /> |
| | | <option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.2.0" /> |
| | | <option name="buildOnly" value="true" /> |
| | | <option name="sourceFilePath" value="ruoyi-extend/ruoyi-powerjob-server/Dockerfile" /> |
| | | <option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" /> |
| | | </settings> |
| | | </deployment> |
| | | <method v="2" /> |
| | |
| | | [](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE) |
| | | [](https://www.jetbrains.com/?from=RuoYi-Vue-Plus) |
| | | <br> |
| | | [](https://gitee.com/dromara/RuoYi-Vue-Plus) |
| | | [](https://gitee.com/dromara/RuoYi-Vue-Plus) |
| | | []() |
| | | []() |
| | | []() |
| | |
| | | |
| | | ## èµå©å |
| | | |
| | | MaxKey - https://gitee.com/dromara/MaxKey <br> |
| | | CCFlow - https://gitee.com/opencc/RuoYi-JFlow <br> |
| | | MaxKey ä¸çé¢å
åç¹ç»å½äº§å - https://gitee.com/dromara/MaxKey <br> |
| | | CCFlow é©°èä½ä»£ç -æµç¨-表å - https://gitee.com/opencc/RuoYi-JFlow <br> |
| | | æ°èµç§æ 软件å®å¶å¼åAPPå°ç¨åºç - http://www.shuduokeji.com/ <br> |
| | | å¼è¿ä¿¡æ¯ 软件å¼åå¹³å° - https://www.jnpfsoft.com/index.html?from=plus-doc <br> |
| | | [å¦ä½æä¸ºèµå©å å 群èç³»ä½è
详è°](https://plus-doc.dromara.org/#/common/add_group) |
| | | |
| | | # æ¬æ¡æ¶ä¸RuoYiçåè½å·®å¼ |
| | |
| | | | åºåå | éç¨ Jackson Spring宿¹å
ç½®åºåå é è°±!!! | éç¨ fastjson bugjson è¿è¿é»å | |
| | | | åå¸å¼å¹ç | åèç¾å¢GTISé²éç³»ç»ç®åå®ç°(ç»èå¯çææ¡£) | æå¨ç¼å注解åºäºaopå®ç° | |
| | | | åå¸å¼é | éç¨ Lock4j åºå±åºäº Redisson | æ | |
| | | | åå¸å¼ä»»å¡è°åº¦ | éç¨ PowerJob å¤©çæ¯æåå¸å¼ ç»ä¸ç管çä¸å¿ | éç¨ Quartz åºäºæ°æ®åºéæ§è½å·® é群éè¦åå¾å¤é
ç½®ä¸æ¹é | |
| | | | åå¸å¼ä»»å¡è°åº¦ | éç¨ SnailJob å¤©çæ¯æåå¸å¼ ç»ä¸ç管çä¸å¿ æ¯æå¤ç§æ°æ®åº æ¯æåçéè¯DAG任塿µç | éç¨ Quartz åºäºæ°æ®åºéæ§è½å·® é群éè¦åå¾å¤é
ç½®ä¸æ¹é | |
| | | | æä»¶åå¨ | éç¨ Minio åå¸å¼æä»¶åå¨ å¤©çæ¯æå¤æºãå¤ç¡¬çãå¤åçãå¤å¯æ¬åå¨<br/>æ¯ææé管ç å®å
¨å¯é æä»¶å¯å å¯åå¨ | éç¨ æ¬æºæä»¶åå¨ æä»¶è£¸æ¼ æä¸¢å¤±æ³æ¼ 䏿¯æé群æåç¹æåº | |
| | | | äºåå¨ | éç¨ AWS S3 å议客æ·ç«¯ æ¯æ ä¸çãé¿éãè
¾è®¯ çä¸åæ¯æS3åè®®çåå®¶ | 䏿¯æ | |
| | | | çä¿¡ | éç¨ sms4j çä¿¡èåå
æ¯ææ°åç§çä¿¡åå®¶ åªéå¨ymlé
置好åå®¶å¯é¥å³å¯ä½¿ç¨ å¯å¤åå®¶å
±ç¨ | 䏿¯æ | |
| | |
| | | <description>RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</description> |
| | | |
| | | <properties> |
| | | <revision>5.1.2</revision> |
| | | <spring-boot.version>3.1.7</spring-boot.version> |
| | | <revision>5.2.0-BETA</revision> |
| | | <spring-boot.version>3.2.5</spring-boot.version> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> |
| | | <java.version>17</java.version> |
| | | <spring-boot.mybatis>3.0.3</spring-boot.mybatis> |
| | | <springdoc.version>2.2.0</springdoc.version> |
| | | <mybatis.version>3.5.16</mybatis.version> |
| | | <springdoc.version>2.5.0</springdoc.version> |
| | | <therapi-javadoc.version>0.15.0</therapi-javadoc.version> |
| | | <poi.version>5.2.3</poi.version> |
| | | <easyexcel.version>3.3.3</easyexcel.version> |
| | | <easyexcel.version>3.3.4</easyexcel.version> |
| | | <velocity.version>2.3</velocity.version> |
| | | <satoken.version>1.37.0</satoken.version> |
| | | <mybatis-plus.version>3.5.4</mybatis-plus.version> |
| | | <satoken.version>1.38.0</satoken.version> |
| | | <mybatis-plus.version>3.5.6</mybatis-plus.version> |
| | | <p6spy.version>3.9.1</p6spy.version> |
| | | <hutool.version>5.8.22</hutool.version> |
| | | <hutool.version>5.8.27</hutool.version> |
| | | <okhttp.version>4.10.0</okhttp.version> |
| | | <spring-boot-admin.version>3.1.8</spring-boot-admin.version> |
| | | <redisson.version>3.24.3</redisson.version> |
| | | <lock4j.version>2.2.5</lock4j.version> |
| | | <dynamic-ds.version>4.2.0</dynamic-ds.version> |
| | | <spring-boot-admin.version>3.2.3</spring-boot-admin.version> |
| | | <redisson.version>3.29.0</redisson.version> |
| | | <lock4j.version>2.2.7</lock4j.version> |
| | | <dynamic-ds.version>4.3.0</dynamic-ds.version> |
| | | <alibaba-ttl.version>2.14.4</alibaba-ttl.version> |
| | | <powerjob.version>4.3.6</powerjob.version> |
| | | <mapstruct-plus.version>1.3.5</mapstruct-plus.version> |
| | | <snailjob.version>1.0.0-beta1</snailjob.version> |
| | | <mapstruct-plus.version>1.3.6</mapstruct-plus.version> |
| | | <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version> |
| | | <lombok.version>1.18.30</lombok.version> |
| | | <lombok.version>1.18.32</lombok.version> |
| | | <bouncycastle.version>1.76</bouncycastle.version> |
| | | <justauth.version>1.16.6</justauth.version> |
| | | <!-- 离线IPå°åå®ä½åº --> |
| | | <ip2region.version>2.7.0</ip2region.version> |
| | | |
| | | <!-- OSS é
ç½® --> |
| | | <aws-java-sdk-s3.version>1.12.600</aws-java-sdk-s3.version> |
| | | <aws.sdk.version>2.25.15</aws.sdk.version> |
| | | <aws.crt.version>0.29.13</aws.crt.version> |
| | | <!-- SMS é
ç½® --> |
| | | <sms4j.version>2.2.0</sms4j.version> |
| | | <sms4j.version>3.2.1</sms4j.version> |
| | | <!-- éå¶æ¡æ¶ä¸çfastjsonçæ¬ --> |
| | | <fastjson.version>1.2.83</fastjson.version> |
| | | |
| | |
| | | <maven-compiler-plugin.verison>3.11.0</maven-compiler-plugin.verison> |
| | | <maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version> |
| | | <flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version> |
| | | |
| | | <!--工使µé
ç½®--> |
| | | <flowable.version>7.0.0</flowable.version> |
| | | </properties> |
| | | |
| | | <profiles> |
| | |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-bom</artifactId> |
| | | <version>${hutool.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-bom</artifactId> |
| | | <version>${flowable.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | <version>${spring-boot.mybatis}</version> |
| | | <groupId>org.mybatis</groupId> |
| | | <artifactId>mybatis</artifactId> |
| | | <version>${mybatis.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | <artifactId>mybatis-plus-spring-boot3-starter</artifactId> |
| | | <version>${mybatis-plus.version}</version> |
| | | </dependency> |
| | | |
| | |
| | | <version>${okhttp.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- AWS SDK for Java 2.x --> |
| | | <dependency> |
| | | <groupId>com.amazonaws</groupId> |
| | | <artifactId>aws-java-sdk-s3</artifactId> |
| | | <version>${aws-java-sdk-s3.version}</version> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>s3</artifactId> |
| | | <version>${aws.sdk.version}</version> |
| | | </dependency> |
| | | <!-- 使ç¨AWSåºäº CRT ç S3 客æ·ç«¯ --> |
| | | <dependency> |
| | | <groupId>software.amazon.awssdk.crt</groupId> |
| | | <artifactId>aws-crt</artifactId> |
| | | <version>${aws.crt.version}</version> |
| | | </dependency> |
| | | <!-- åºäº AWS CRT ç S3 客æ·ç«¯çæ§è½å¢å¼ºç S3 ä¼ è¾ç®¡çå¨ --> |
| | | <dependency> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>s3-transfer-manager</artifactId> |
| | | <version>${aws.sdk.version}</version> |
| | | </dependency> |
| | | <!--çä¿¡sms4j--> |
| | | <dependency> |
| | |
| | | <version>${lock4j.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- PowerJob --> |
| | | <!-- SnailJob Client --> |
| | | <dependency> |
| | | <groupId>tech.powerjob</groupId> |
| | | <artifactId>powerjob-worker-spring-boot-starter</artifactId> |
| | | <version>${powerjob.version}</version> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-starter</artifactId> |
| | | <version>${snailjob.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>tech.powerjob</groupId> |
| | | <artifactId>powerjob-official-processors</artifactId> |
| | | <version>${powerjob.version}</version> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-job-core</artifactId> |
| | | <version>${snailjob.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-demo</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- 工使µæ¨¡å --> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-workflow</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | |
| | | <artifactId>maven-surefire-plugin</artifactId> |
| | | <version>${maven-surefire-plugin.version}</version> |
| | | <configuration> |
| | | <argLine>-Dfile.encoding=UTF-8</argLine> |
| | | <!-- æ ¹æ®æå
ç¯å¢æ§è¡å¯¹åºç@Tagæµè¯æ¹æ³ --> |
| | | <groups>${profiles.active}</groups> |
| | | <!-- æé¤æ ç¾ --> |
| | |
| | | # åºç¨åç§° 妿æ³åºåé群èç¹çæ§ æ¹æä¸åçåç§°å³å¯ |
| | | #-Dskywalking.agent.service_name=ruoyi-server \ |
| | | #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ |
| | | -jar app.jar \ |
| | | -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} |
| | | -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \ |
| | | -jar app.jar |
| | | |
| | |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-mail</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | </dependency> |
| | | |
| | |
| | | <artifactId>ruoyi-demo</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- 工使µæ¨¡å --> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-workflow</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>de.codecentric</groupId> |
| | | <artifactId>spring-boot-admin-starter-client</artifactId> |
| | |
| | | <artifactId>JustAuth</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- SnailJob client --> |
| | | <dependency> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-starter</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-job-core</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- skywalking æ´å logback --> |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>org.apache.skywalking</groupId>--> |
| | |
| | | import org.dromara.common.social.config.properties.SocialProperties; |
| | | import org.dromara.common.social.utils.SocialUtils; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.common.websocket.dto.WebSocketMessageDto; |
| | | import org.dromara.common.websocket.utils.WebSocketUtils; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.bo.SysTenantBo; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysTenantVo; |
| | | import org.dromara.system.service.ISysClientService; |
| | | import org.dromara.system.service.ISysConfigService; |
| | |
| | | // ææç±»åå客æ·ç«¯id |
| | | String clientId = loginBody.getClientId(); |
| | | String grantType = loginBody.getGrantType(); |
| | | SysClient client = clientService.queryByClientId(clientId); |
| | | SysClientVo client = clientService.queryByClientId(clientId); |
| | | // æ¥è¯¢ä¸å° client æ client å
ä¸å
å« grantType |
| | | if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) { |
| | | log.info("客æ·ç«¯id: {} 认è¯ç±»åï¼{} å¼å¸¸!.", clientId, grantType); |
| | |
| | | |
| | | Long userId = LoginHelper.getUserId(); |
| | | scheduledExecutorService.schedule(() -> { |
| | | WebSocketUtils.sendMessage(userId, "欢è¿ç»å½RuoYi-Vue-Plusåå°ç®¡çç³»ç»"); |
| | | WebSocketMessageDto dto = new WebSocketMessageDto(); |
| | | dto.setMessage("欢è¿ç»å½RuoYi-Vue-Plusåå°ç®¡çç³»ç»"); |
| | | dto.setSessionKeys(List.of(userId)); |
| | | WebSocketUtils.publishMessage(dto); |
| | | }, 3, TimeUnit.SECONDS); |
| | | return R.ok(loginVo); |
| | | } |
| | |
| | | import cn.hutool.captcha.generator.CodeGenerator; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.domain.R; |
| | |
| | | import org.dromara.sms4j.api.SmsBlend; |
| | | import org.dromara.sms4j.api.entity.SmsResponse; |
| | | import org.dromara.sms4j.core.factory.SmsFactory; |
| | | import org.dromara.sms4j.provider.enumerate.SupplierType; |
| | | import org.dromara.web.domain.vo.CaptchaVo; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.expression.Expression; |
| | | import org.springframework.expression.ExpressionParser; |
| | | import org.springframework.expression.spel.standard.SpelExpressionParser; |
| | |
| | | String templateId = ""; |
| | | LinkedHashMap<String, String> map = new LinkedHashMap<>(1); |
| | | map.put("code", code); |
| | | SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); |
| | | SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
| | | SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map); |
| | | if (!"OK".equals(smsResponse.getCode())) { |
| | | if (!smsResponse.isSuccess()) { |
| | | log.error("éªè¯ç çä¿¡åéå¼å¸¸ => {}", smsResponse); |
| | | return R.fail(smsResponse.getMessage()); |
| | | return R.fail(smsResponse.getData().toString()); |
| | | } |
| | | return R.ok(); |
| | | } |
| | |
| | | AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); |
| | | captcha.setGenerator(codeGenerator); |
| | | captcha.createCode(); |
| | | // å¦ææ¯æ°å¦éªè¯ç ï¼ä½¿ç¨SpEL表达å¼å¤çéªè¯ç ç»æ |
| | | String code = captcha.getCode(); |
| | | if (isMath) { |
| | | ExpressionParser parser = new SpelExpressionParser(); |
| | |
| | | @AutoMapper(target = SysTenantVo.class) |
| | | public class TenantListVo { |
| | | |
| | | /** |
| | | * ç§æ·ç¼å· |
| | | */ |
| | | private String tenantId; |
| | | |
| | | /** |
| | | * ä¼ä¸åç§° |
| | | */ |
| | | private String companyName; |
| | | |
| | | /** |
| | | * åå |
| | | */ |
| | | private String domain; |
| | | |
| | | } |
| | |
| | | import org.dromara.common.core.constant.CacheConstants; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.common.core.domain.dto.UserOnlineDTO; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.utils.MessageUtils; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | |
| | | import org.dromara.common.log.event.LogininforEvent; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.web.service.SysLoginService; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { |
| | | UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); |
| | | String ip = ServletUtils.getClientIP(); |
| | | LoginUser user = LoginHelper.getLoginUser(); |
| | | UserOnlineDTO dto = new UserOnlineDTO(); |
| | | dto.setIpaddr(ip); |
| | | dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); |
| | |
| | | dto.setOs(userAgent.getOs().getName()); |
| | | dto.setLoginTime(System.currentTimeMillis()); |
| | | dto.setTokenId(tokenValue); |
| | | dto.setUserName(user.getUsername()); |
| | | dto.setClientKey(user.getClientKey()); |
| | | dto.setDeviceType(user.getDeviceType()); |
| | | dto.setDeptName(user.getDeptName()); |
| | | if(tokenConfig.getTimeout() == -1) { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); |
| | | } else { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); |
| | | } |
| | | String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY); |
| | | String tenantId = (String) loginModel.getExtra(LoginHelper.TENANT_KEY); |
| | | dto.setUserName(username); |
| | | dto.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY)); |
| | | dto.setDeviceType(loginModel.getDevice()); |
| | | dto.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY)); |
| | | TenantHelper.dynamic(tenantId, () -> { |
| | | if(tokenConfig.getTimeout() == -1) { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); |
| | | } else { |
| | | RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); |
| | | } |
| | | }); |
| | | // è®°å½ç»å½æ¥å¿ |
| | | LogininforEvent logininforEvent = new LogininforEvent(); |
| | | logininforEvent.setTenantId(user.getTenantId()); |
| | | logininforEvent.setUsername(user.getUsername()); |
| | | logininforEvent.setTenantId(tenantId); |
| | | logininforEvent.setUsername(username); |
| | | logininforEvent.setStatus(Constants.LOGIN_SUCCESS); |
| | | logininforEvent.setMessage(MessageUtils.message("user.login.success")); |
| | | logininforEvent.setRequest(ServletUtils.getRequest()); |
| | | SpringUtils.context().publishEvent(logininforEvent); |
| | | // æ´æ°ç»å½ä¿¡æ¯ |
| | | loginService.recordLoginInfo(user.getUserId(), ip); |
| | | loginService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip); |
| | | log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); |
| | | } |
| | | |
| | |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.web.domain.vo.LoginVo; |
| | | |
| | | /** |
| | |
| | | |
| | | /** |
| | | * ç»å½ |
| | | * |
| | | * @param body ç»å½å¯¹è±¡ |
| | | * @param client ææç®¡çè§å¾å¯¹è±¡ |
| | | * @param grantType ææç±»å |
| | | * @return ç»å½éªè¯ä¿¡æ¯ |
| | | */ |
| | | static LoginVo login(String body, SysClient client, String grantType) { |
| | | static LoginVo login(String body, SysClientVo client, String grantType) { |
| | | // ææç±»åå客æ·ç«¯id |
| | | String beanName = grantType + BASE_NAME; |
| | | if (!SpringUtils.containsBean(beanName)) { |
| | |
| | | |
| | | /** |
| | | * ç»å½ |
| | | * |
| | | * @param body ç»å½å¯¹è±¡ |
| | | * @param client ææç®¡çè§å¾å¯¹è±¡ |
| | | * @return ç»å½éªè¯ä¿¡æ¯ |
| | | */ |
| | | LoginVo login(String body, SysClient client); |
| | | LoginVo login(String body, SysClientVo client); |
| | | |
| | | } |
| | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.lock.annotation.Lock4j; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.zhyd.oauth.model.AuthUser; |
| | |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.enums.LoginType; |
| | | import org.dromara.common.core.enums.TenantStatus; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.exception.user.UserException; |
| | | import org.dromara.common.core.utils.*; |
| | | import org.dromara.common.log.event.LogininforEvent; |
| | |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.bo.SysSocialBo; |
| | | import org.dromara.system.domain.vo.SysSocialVo; |
| | | import org.dromara.system.domain.vo.SysTenantVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.domain.vo.*; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | | import org.dromara.system.service.ISysPermissionService; |
| | | import org.dromara.system.service.ISysSocialService; |
| | | import org.dromara.system.service.ISysTenantService; |
| | | import org.dromara.system.service.*; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | |
| | | private final ISysTenantService tenantService; |
| | | private final ISysPermissionService permissionService; |
| | | private final ISysSocialService sysSocialService; |
| | | private final ISysRoleService roleService; |
| | | private final ISysDeptService deptService; |
| | | private final SysUserMapper userMapper; |
| | | |
| | | |
| | |
| | | * ç»å®ç¬¬ä¸æ¹ç¨æ· |
| | | * |
| | | * @param authUserData ææååºå®ä½ |
| | | * @return ç»ä¸ååºå®ä½ |
| | | */ |
| | | @Lock4j |
| | | public void socialRegister(AuthUser authUserData) { |
| | | String authId = authUserData.getSource() + authUserData.getUuid(); |
| | | // ç¬¬ä¸æ¹ç¨æ·ä¿¡æ¯ |
| | | SysSocialBo bo = BeanUtil.toBean(authUserData, SysSocialBo.class); |
| | | BeanUtil.copyProperties(authUserData.getToken(), bo); |
| | | bo.setUserId(LoginHelper.getUserId()); |
| | | Long userId = LoginHelper.getUserId(); |
| | | bo.setUserId(userId); |
| | | bo.setAuthId(authId); |
| | | bo.setOpenId(authUserData.getUuid()); |
| | | bo.setUserName(authUserData.getUsername()); |
| | | bo.setNickName(authUserData.getNickname()); |
| | | List<SysSocialVo> checkList = sysSocialService.selectByAuthId(authId); |
| | | if (CollUtil.isNotEmpty(checkList)) { |
| | | throw new ServiceException("æ¤ä¸æ¹è´¦å·å·²ç»è¢«ç»å®!"); |
| | | } |
| | | // æ¥è¯¢æ¯å¦å·²ç»ç»å®ç¨æ· |
| | | List<SysSocialVo> list = sysSocialService.selectByAuthId(authId); |
| | | SysSocialBo params = new SysSocialBo(); |
| | | params.setUserId(userId); |
| | | params.setSource(bo.getSource()); |
| | | List<SysSocialVo> list = sysSocialService.queryList(params); |
| | | if (CollUtil.isEmpty(list)) { |
| | | // 没æç»å®ç¨æ·, æ°å¢ç¨æ·ä¿¡æ¯ |
| | | sysSocialService.insertByBo(bo); |
| | |
| | | // æ´æ°ç¨æ·ä¿¡æ¯ |
| | | bo.setId(list.get(0).getId()); |
| | | sysSocialService.updateByBo(bo); |
| | | // 妿è¦ç»å®çå¹³å°è´¦å·å·²ç»è¢«ç»å®è¿äº æ¯å¦æå¼å¸¸èªè¡å³æ |
| | | // throw new ServiceException("æ¤å¹³å°è´¦å·å·²ç»è¢«ç»å®!"); |
| | | } |
| | | } |
| | | |
| | |
| | | SpringUtils.context().publishEvent(logininforEvent); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æå»ºç»å½ç¨æ· |
| | | */ |
| | |
| | | loginUser.setUserType(user.getUserType()); |
| | | loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); |
| | | loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); |
| | | loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName()); |
| | | List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class); |
| | | loginUser.setRoles(roles); |
| | | TenantHelper.dynamic(user.getTenantId(), () -> { |
| | | SysDeptVo dept = null; |
| | | if (ObjectUtil.isNotNull(user.getDeptId())) { |
| | | dept = deptService.selectDeptById(user.getDeptId()); |
| | | } |
| | | loginUser.setDeptName(ObjectUtil.isNull(dept) ? "" : dept.getDeptName()); |
| | | loginUser.setDeptCategory(ObjectUtil.isNull(dept) ? "" : dept.getDeptCategory()); |
| | | List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId()); |
| | | loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); |
| | | }); |
| | | return loginUser; |
| | | } |
| | | |
| | |
| | | package org.dromara.web.service; |
| | | |
| | | import cn.dev33.satoken.secure.BCrypt; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.Constants; |
| | |
| | | |
| | | boolean exist = TenantHelper.dynamic(tenantId, () -> { |
| | | return userMapper.exists(new LambdaQueryWrapper<SysUser>() |
| | | .eq(SysUser::getUserName, sysUser.getUserName()) |
| | | .ne(ObjectUtil.isNotNull(sysUser.getUserId()), SysUser::getUserId, sysUser.getUserId())); |
| | | .eq(SysUser::getUserName, sysUser.getUserName())); |
| | | }); |
| | | if (exist) { |
| | | throw new UserException("user.register.save.error", username); |
| | |
| | | * @param uuid å¯ä¸æ è¯ |
| | | */ |
| | | public void validateCaptcha(String tenantId, String username, String code, String uuid) { |
| | | String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, ""); |
| | | String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.blankToDefault(uuid, ""); |
| | | String captcha = RedisUtils.getCacheObject(verifyKey); |
| | | RedisUtils.deleteObject(verifyKey); |
| | | if (captcha == null) { |
| | |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | | import org.dromara.web.domain.vo.LoginVo; |
| | |
| | | private final SysUserMapper userMapper; |
| | | |
| | | @Override |
| | | public LoginVo login(String body, SysClient client) { |
| | | public LoginVo login(String body, SysClientVo client) { |
| | | EmailLoginBody loginBody = JsonUtils.parseObject(body, EmailLoginBody.class); |
| | | ValidatorUtils.validate(loginBody); |
| | | String tenantId = loginBody.getTenantId(); |
| | |
| | | |
| | | private SysUserVo loadUserByEmail(String tenantId, String email) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getEmail, SysUser::getStatus) |
| | | .eq(SysUser::getEmail, email)); |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("ç»å½ç¨æ·ï¼{} ä¸åå¨.", email); |
| | | throw new UserException("user.not.exists", email); |
| | |
| | | log.info("ç»å½ç¨æ·ï¼{} 已被åç¨.", email); |
| | | throw new UserException("user.blocked", email); |
| | | } |
| | | return userMapper.selectUserByEmail(email); |
| | | return user; |
| | | }); |
| | | } |
| | | |
| | |
| | | import org.dromara.common.web.config.properties.CaptchaProperties; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | | import org.dromara.web.domain.vo.LoginVo; |
| | |
| | | private final SysUserMapper userMapper; |
| | | |
| | | @Override |
| | | public LoginVo login(String body, SysClient client) { |
| | | public LoginVo login(String body, SysClientVo client) { |
| | | PasswordLoginBody loginBody = JsonUtils.parseObject(body, PasswordLoginBody.class); |
| | | ValidatorUtils.validate(loginBody); |
| | | String tenantId = loginBody.getTenantId(); |
| | |
| | | |
| | | private SysUserVo loadUserByUsername(String tenantId, String username) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getUserName, SysUser::getStatus) |
| | | .eq(SysUser::getUserName, username)); |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("ç»å½ç¨æ·ï¼{} ä¸åå¨.", username); |
| | | throw new UserException("user.not.exists", username); |
| | |
| | | log.info("ç»å½ç¨æ·ï¼{} 已被åç¨.", username); |
| | | throw new UserException("user.blocked", username); |
| | | } |
| | | return userMapper.selectUserByUserName(username); |
| | | return user; |
| | | }); |
| | | } |
| | | |
| | |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | | import org.dromara.web.domain.vo.LoginVo; |
| | |
| | | private final SysUserMapper userMapper; |
| | | |
| | | @Override |
| | | public LoginVo login(String body, SysClient client) { |
| | | public LoginVo login(String body, SysClientVo client) { |
| | | SmsLoginBody loginBody = JsonUtils.parseObject(body, SmsLoginBody.class); |
| | | ValidatorUtils.validate(loginBody); |
| | | String tenantId = loginBody.getTenantId(); |
| | |
| | | |
| | | private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getPhonenumber, SysUser::getStatus) |
| | | .eq(SysUser::getPhonenumber, phonenumber)); |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("ç»å½ç¨æ·ï¼{} ä¸åå¨.", phonenumber); |
| | | throw new UserException("user.not.exists", phonenumber); |
| | |
| | | log.info("ç»å½ç¨æ·ï¼{} 已被åç¨.", phonenumber); |
| | | throw new UserException("user.blocked", phonenumber); |
| | | } |
| | | return userMapper.selectUserByPhonenumber(phonenumber); |
| | | return user; |
| | | }); |
| | | } |
| | | |
| | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.http.HttpUtil; |
| | | import cn.hutool.http.Method; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.zhyd.oauth.model.AuthResponse; |
| | |
| | | import org.dromara.common.social.config.properties.SocialProperties; |
| | | import org.dromara.common.social.utils.SocialUtils; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysSocialVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | |
| | | * @param client 客æ·ç«¯ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public LoginVo login(String body, SysClient client) { |
| | | public LoginVo login(String body, SysClientVo client) { |
| | | SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class); |
| | | ValidatorUtils.validate(loginBody); |
| | | AuthResponse<AuthUser> response = SocialUtils.loginAuth( |
| | |
| | | if (CollUtil.isEmpty(list)) { |
| | | throw new ServiceException("ä½ è¿æ²¡æç»å®ç¬¬ä¸æ¹è´¦å·ï¼ç»å®åæå¯ä»¥ç»å½ï¼"); |
| | | } |
| | | Optional<SysSocialVo> opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny(); |
| | | if (opt.isEmpty()) { |
| | | throw new ServiceException("对ä¸èµ·ï¼ä½ 没ææéç»å½å½åç§æ·ï¼"); |
| | | SysSocialVo social; |
| | | if (TenantHelper.isEnable()) { |
| | | Optional<SysSocialVo> opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny(); |
| | | if (opt.isEmpty()) { |
| | | throw new ServiceException("对ä¸èµ·ï¼ä½ 没ææéç»å½å½åç§æ·ï¼"); |
| | | } |
| | | social = opt.get(); |
| | | } else { |
| | | social = list.get(0); |
| | | } |
| | | SysSocialVo social = opt.get(); |
| | | // æ¥æ¾ç¨æ· |
| | | SysUserVo user = loadUser(social.getTenantId(), social.getUserId()); |
| | | |
| | |
| | | |
| | | private SysUserVo loadUser(String tenantId, Long userId) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getUserName, SysUser::getStatus) |
| | | .eq(SysUser::getUserId, userId)); |
| | | SysUserVo user = userMapper.selectVoById(userId); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("ç»å½ç¨æ·ï¼{} ä¸åå¨.", ""); |
| | | throw new UserException("user.not.exists", ""); |
| | |
| | | log.info("ç»å½ç¨æ·ï¼{} 已被åç¨.", ""); |
| | | throw new UserException("user.blocked", ""); |
| | | } |
| | | return userMapper.selectUserByUserName(user.getUserName()); |
| | | return user; |
| | | }); |
| | | } |
| | | |
| | |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.web.domain.vo.LoginVo; |
| | | import org.dromara.web.service.IAuthStrategy; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * é®ä»¶è®¤è¯çç¥ |
| | | * å°ç¨åºè®¤è¯çç¥ |
| | | * |
| | | * @author Michelle.Chung |
| | | */ |
| | |
| | | private final SysLoginService loginService; |
| | | |
| | | @Override |
| | | public LoginVo login(String body, SysClient client) { |
| | | public LoginVo login(String body, SysClientVo client) { |
| | | XcxLoginBody loginBody = JsonUtils.parseObject(body, XcxLoginBody.class); |
| | | ValidatorUtils.validate(loginBody); |
| | | // xcxCode 为 å°ç¨åºè°ç¨ wx.login ææåè·å |
| | |
| | | username: ruoyi |
| | | password: 123456 |
| | | |
| | | --- # powerjob é
ç½® |
| | | powerjob: |
| | | worker: |
| | | # å¦ä½å¼å¯è°åº¦ä¸å¿è¯·æ¥çææ¡£æç¨ |
| | | enabled: false |
| | | # éè¦å
å¨ powerjob ç»å½é¡µæ§è¡åºç¨æ³¨ååæè½ä½¿ç¨ |
| | | app-name: ruoyi-worker |
| | | allow-lazy-connect-server: false |
| | | max-appended-wf-context-length: 4096 |
| | | max-result-length: 4096 |
| | | # 28080 ç«¯å£ éç主åºç¨ç«¯å£é£é¸ é¿å
é群å²çª |
| | | port: 2${server.port} |
| | | protocol: http |
| | | server-address: 127.0.0.1:7700 |
| | | store-strategy: disk |
| | | --- # snail-job é
ç½® |
| | | snail-job: |
| | | enabled: true |
| | | # éè¦å¨ SnailJob åå°ç»ç®¡çå建对åºåç§°çç»,ç¶åå建任å¡çæ¶å鿩坹åºçç»,æè½æ£ç¡®åæ´¾ä»»å¡ |
| | | group-name: "ruoyi_group" |
| | | # SnailJob æ¥å
¥éªè¯ä»¤ç è¯¦è§ script/sql/snail_job.sql `sj_group_config` 表 |
| | | token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT" |
| | | server: |
| | | host: 127.0.0.1 |
| | | port: 1788 |
| | | # è¯¦è§ script/sql/snail_job.sql `sj_namespace` 表 |
| | | namespace: ${spring.profiles.active} |
| | | |
| | | |
| | | --- # æ°æ®æºé
ç½® |
| | | spring: |
| | |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | # jdbc ææåæ°é
ç½®åè https://lionli.blog.csdn.net/article/details/122018562 |
| | | # rewriteBatchedStatements=true æ¹å¤çä¼å 大å¹
æåæ¹éæå
¥æ´æ°å 餿§è½(å¯¹æ°æ®åºææ§è½æè ä½¿ç¨æ¹éæä½åºèèæ§è½é®é¢) |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true |
| | | username: root |
| | | password: root |
| | | # ä»åºæ°æ®æº |
| | |
| | | lazy: true |
| | | type: ${spring.datasource.type} |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true |
| | | username: |
| | | password: |
| | | # oracle: |
| | |
| | | connectionTimeout: 0 |
| | | |
| | | --- # sms çä¿¡ æ¯æ é¿éäº è
¾è®¯äº äºç ççåå¼åæ ·ççä¿¡æå¡å |
| | | # https://wind.kim/doc/start ææ¡£å°å å个ååå¯åæ¶ä½¿ç¨ |
| | | # https://sms4j.com/doc3/ å·®å¼é
ç½®ææ¡£å°å æ¯æåååå¤é
ç½®ï¼å¯ä»¥é
ç½®å¤ä¸ªåæ¶ä½¿ç¨ |
| | | sms: |
| | | # é¿éäº dysmsapi.aliyuncs.com |
| | | alibaba: |
| | | #请æ±å°å é»è®¤ä¸º dysmsapi.aliyuncs.com 妿 ç¹æ®æ¹åå¯ä»¥ä¸ç¨è®¾ç½® |
| | | requestUrl: dysmsapi.aliyuncs.com |
| | | #é¿éäºçaccessKey |
| | | accessKeyId: xxxxxxx |
| | | #é¿éäºçaccessKeySecret |
| | | accessKeySecret: xxxxxxx |
| | | #çä¿¡ç¾å |
| | | signature: æµè¯ |
| | | tencent: |
| | | #请æ±å°åé»è®¤ä¸º sms.tencentcloudapi.com 妿 ç¹æ®æ¹åå¯ä¸ç¨è®¾ç½® |
| | | requestUrl: sms.tencentcloudapi.com |
| | | #è
¾è®¯äºçaccessKey |
| | | accessKeyId: xxxxxxx |
| | | #è
¾è®¯äºçaccessKeySecret |
| | | accessKeySecret: xxxxxxx |
| | | #çä¿¡ç¾å |
| | | signature: æµè¯ |
| | | #çä¿¡sdkAppId |
| | | sdkAppId: appid |
| | | #å°åä¿¡æ¯é»è®¤ä¸º ap-guangzhou 妿 ç¹æ®æ¹åå¯ä¸ç¨è®¾ç½® |
| | | territory: ap-guangzhou |
| | | # é
ç½®æºç±»åç¨äºæ å®é
ç½®æ¥æº(interface,yaml) |
| | | config-type: yaml |
| | | # ç¨äºæ å®ymlä¸çé
ç½®æ¯å¦å¼å¯çä¿¡æ¦æªï¼æ¥å£é
ç½®ä¸åæ¤éå¶ |
| | | restricted: true |
| | | # çä¿¡æ¦æªéå¶åææºå·æ¯åéæå¤§åéï¼åªå¯¹å¼å¯äºæ¦æªçé
ç½®ææ |
| | | minute-max: 1 |
| | | # çä¿¡æ¦æªéå¶åææºå·æ¯æ¥æå¤§åééï¼åªå¯¹å¼å¯äºæ¦æªçé
ç½®ææ |
| | | account-max: 30 |
| | | # 以ä¸é
ç½®æ¥èªäº org.dromara.sms4j.provider.config.BaseConfigç±»ä¸ |
| | | blends: |
| | | # å¯ä¸ID ç¨äºåéç信寻æ¾å
·ä½é
ç½® é便å®ä¹å«ç¨ä¸æå³å¯ |
| | | # å¯ä»¥åæ¶åå¨ä¸¤ä¸ªç¸ååå ä¾å¦: ali1 ali2 两个ä¸åçé¿éçä¿¡è´¦å· ä¹å¯ç¨äºåºåç§æ· |
| | | config1: |
| | | # æ¡æ¶å®ä¹çåååç§°æ è¯ï¼æ 宿¤é
ç½®æ¯åªä¸ªååï¼è¯¦ç»è¯·çååæ è¯ä»ç»é¨å |
| | | supplier: alibaba |
| | | # æäºç§°ä¸ºaccessKeyæäºç§°ä¹ä¸ºapiKeyï¼ä¹æç§°ä¸ºsdkKeyæè
appIdã |
| | | access-key-id: æ¨çaccessKey |
| | | # 称为accessSecretæäºç§°ä¹ä¸ºapiSecret |
| | | access-key-secret: æ¨çaccessKeySecret |
| | | signature: æ¨ççä¿¡ç¾å |
| | | sdk-app-id: æ¨çsdkAppId |
| | | config2: |
| | | # ååæ è¯ï¼æ 宿¤é
ç½®æ¯åªä¸ªååï¼è¯¦ç»è¯·çååæ è¯ä»ç»é¨å |
| | | supplier: tencent |
| | | access-key-id: æ¨çaccessKey |
| | | access-key-secret: æ¨çaccessKeySecret |
| | | signature: æ¨ççä¿¡ç¾å |
| | | sdk-app-id: æ¨çsdkAppId |
| | | |
| | | |
| | | --- # 䏿¹ææ |
| | | justauth: |
| | | enabled: true |
| | | # å端å¤ç½è®¿é®å°å |
| | | address: http://localhost:80 |
| | | type: |
| | |
| | | client-id: 876892492581044224 |
| | | client-secret: x1Y5MTMwNzIwMjMxNTM4NDc3Mzche8 |
| | | redirect-uri: ${justauth.address}/social-callback?source=maxkey |
| | | topiam: |
| | | # topiam æå¡å¨å°å |
| | | server-url: http://127.0.0.1:1989/api/v1/authorize/y0q************spq***********8ol |
| | | client-id: 449c4*********937************759 |
| | | client-secret: ac7***********1e0************28d |
| | | redirect-uri: ${justauth.address}/social-callback?source=topiam |
| | | scopes: [openid, email, phone, profile] |
| | | qq: |
| | | client-id: 10**********6 |
| | | client-secret: 1f7d08**********5b7**********29e |
| | |
| | | username: ruoyi |
| | | password: 123456 |
| | | |
| | | --- # powerjob é
ç½® |
| | | powerjob: |
| | | worker: |
| | | # å¦ä½å¼å¯è°åº¦ä¸å¿è¯·æ¥çææ¡£æç¨ |
| | | enabled: false |
| | | # éè¦å
å¨ powerjob ç»å½é¡µæ§è¡åºç¨æ³¨ååæè½ä½¿ç¨ |
| | | app-name: ruoyi-worker |
| | | allow-lazy-connect-server: false |
| | | max-appended-wf-context-length: 4096 |
| | | max-result-length: 4096 |
| | | # 28080 ç«¯å£ éç主åºç¨ç«¯å£é£é¸ é¿å
é群å²çª |
| | | port: 2${server.port} |
| | | protocol: http |
| | | server-address: 127.0.0.1:7700 |
| | | store-strategy: disk |
| | | --- # snail-job é
ç½® |
| | | snail-job: |
| | | enabled: false |
| | | # éè¦å¨ SnailJob åå°ç»ç®¡çå建对åºåç§°çç»,ç¶åå建任å¡çæ¶å鿩坹åºçç»,æè½æ£ç¡®åæ´¾ä»»å¡ |
| | | group-name: "ruoyi_group" |
| | | # SnailJob æ¥å
¥éªè¯ä»¤ç è¯¦è§ script/sql/snail_job.sql `sj_group_config` 表 |
| | | token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT" |
| | | server: |
| | | host: 127.0.0.1 |
| | | port: 1788 |
| | | # è¯¦è§ script/sql/snail_job.sql `sj_namespace` 表 |
| | | namespace: ${spring.profiles.active} |
| | | |
| | | --- # æ°æ®æºé
ç½® |
| | | spring: |
| | |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | # jdbc ææåæ°é
ç½®åè https://lionli.blog.csdn.net/article/details/122018562 |
| | | # rewriteBatchedStatements=true æ¹å¤çä¼å 大å¹
æåæ¹éæå
¥æ´æ°å 餿§è½(å¯¹æ°æ®åºææ§è½æè ä½¿ç¨æ¹éæä½åºèèæ§è½é®é¢) |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true |
| | | username: root |
| | | password: root |
| | | # ä»åºæ°æ®æº |
| | |
| | | lazy: true |
| | | type: ${spring.datasource.type} |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true |
| | | username: |
| | | password: |
| | | # oracle: |
| | |
| | | connectionTimeout: 0 |
| | | |
| | | --- # sms çä¿¡ æ¯æ é¿éäº è
¾è®¯äº äºç ççåå¼åæ ·ççä¿¡æå¡å |
| | | # https://wind.kim/doc/start ææ¡£å°å å个ååå¯åæ¶ä½¿ç¨ |
| | | # https://sms4j.com/doc3/ å·®å¼é
ç½®ææ¡£å°å æ¯æåååå¤é
ç½®ï¼å¯ä»¥é
ç½®å¤ä¸ªåæ¶ä½¿ç¨ |
| | | sms: |
| | | # é¿éäº dysmsapi.aliyuncs.com |
| | | alibaba: |
| | | #请æ±å°å é»è®¤ä¸º dysmsapi.aliyuncs.com 妿 ç¹æ®æ¹åå¯ä»¥ä¸ç¨è®¾ç½® |
| | | requestUrl: dysmsapi.aliyuncs.com |
| | | #é¿éäºçaccessKey |
| | | accessKeyId: xxxxxxx |
| | | #é¿éäºçaccessKeySecret |
| | | accessKeySecret: xxxxxxx |
| | | #çä¿¡ç¾å |
| | | signature: æµè¯ |
| | | tencent: |
| | | #请æ±å°åé»è®¤ä¸º sms.tencentcloudapi.com 妿 ç¹æ®æ¹åå¯ä¸ç¨è®¾ç½® |
| | | requestUrl: sms.tencentcloudapi.com |
| | | #è
¾è®¯äºçaccessKey |
| | | accessKeyId: xxxxxxx |
| | | #è
¾è®¯äºçaccessKeySecret |
| | | accessKeySecret: xxxxxxx |
| | | #çä¿¡ç¾å |
| | | signature: æµè¯ |
| | | #çä¿¡sdkAppId |
| | | sdkAppId: appid |
| | | #å°åä¿¡æ¯é»è®¤ä¸º ap-guangzhou 妿 ç¹æ®æ¹åå¯ä¸ç¨è®¾ç½® |
| | | territory: ap-guangzhou |
| | | # é
ç½®æºç±»åç¨äºæ å®é
ç½®æ¥æº(interface,yaml) |
| | | config-type: yaml |
| | | # ç¨äºæ å®ymlä¸çé
ç½®æ¯å¦å¼å¯çä¿¡æ¦æªï¼æ¥å£é
ç½®ä¸åæ¤éå¶ |
| | | restricted: true |
| | | # çä¿¡æ¦æªéå¶åææºå·æ¯åéæå¤§åéï¼åªå¯¹å¼å¯äºæ¦æªçé
ç½®ææ |
| | | minute-max: 1 |
| | | # çä¿¡æ¦æªéå¶åææºå·æ¯æ¥æå¤§åééï¼åªå¯¹å¼å¯äºæ¦æªçé
ç½®ææ |
| | | account-max: 30 |
| | | # 以ä¸é
ç½®æ¥èªäº org.dromara.sms4j.provider.config.BaseConfigç±»ä¸ |
| | | blends: |
| | | # å¯ä¸ID ç¨äºåéç信寻æ¾å
·ä½é
ç½® é便å®ä¹å«ç¨ä¸æå³å¯ |
| | | # å¯ä»¥åæ¶åå¨ä¸¤ä¸ªç¸ååå ä¾å¦: ali1 ali2 两个ä¸åçé¿éçä¿¡è´¦å· ä¹å¯ç¨äºåºåç§æ· |
| | | config1: |
| | | # æ¡æ¶å®ä¹çåååç§°æ è¯ï¼æ 宿¤é
ç½®æ¯åªä¸ªååï¼è¯¦ç»è¯·çååæ è¯ä»ç»é¨å |
| | | supplier: alibaba |
| | | # æäºç§°ä¸ºaccessKeyæäºç§°ä¹ä¸ºapiKeyï¼ä¹æç§°ä¸ºsdkKeyæè
appIdã |
| | | access-key-id: æ¨çaccessKey |
| | | # 称为accessSecretæäºç§°ä¹ä¸ºapiSecret |
| | | access-key-secret: æ¨çaccessKeySecret |
| | | signature: æ¨ççä¿¡ç¾å |
| | | sdk-app-id: æ¨çsdkAppId |
| | | config2: |
| | | # ååæ è¯ï¼æ 宿¤é
ç½®æ¯åªä¸ªååï¼è¯¦ç»è¯·çååæ è¯ä»ç»é¨å |
| | | supplier: tencent |
| | | access-key-id: æ¨çaccessKey |
| | | access-key-secret: æ¨çaccessKeySecret |
| | | signature: æ¨ççä¿¡ç¾å |
| | | sdk-app-id: æ¨çsdkAppId |
| | | |
| | | --- # 䏿¹ææ |
| | | justauth: |
| | | enabled: true |
| | | # å端å¤ç½è®¿é®å°å |
| | | address: http://localhost:80 |
| | | type: |
| | |
| | | client-id: 876892492581044224 |
| | | client-secret: x1Y5MTMwNzIwMjMxNTM4NDc3Mzche8 |
| | | redirect-uri: ${justauth.address}/social-callback?source=maxkey |
| | | topiam: |
| | | # topiam æå¡å¨å°å |
| | | server-url: http://127.0.0.1:1989/api/v1/authorize/y0q************spq***********8ol |
| | | client-id: 449c4*********937************759 |
| | | client-secret: ac7***********1e0************28d |
| | | redirect-uri: ${justauth.address}/social-callback?source=topiam |
| | | scopes: [ openid, email, phone, profile ] |
| | | qq: |
| | | client-id: 10**********6 |
| | | client-secret: 1f7d08**********5b7**********29e |
| | |
| | | # çæ¬ |
| | | version: ${revision} |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2023 |
| | | copyrightYear: 2024 |
| | | |
| | | captcha: |
| | | enable: true |
| | |
| | | level: |
| | | org.dromara: @logging.level@ |
| | | org.springframework: warn |
| | | tech.powerjob.worker.background: warn |
| | | org.mybatis.spring.mapper: error |
| | | config: classpath:logback-plus.xml |
| | | |
| | | # ç¨æ·é
ç½® |
| | |
| | | spring: |
| | | application: |
| | | name: ${ruoyi.name} |
| | | threads: |
| | | # å¼å¯èæçº¿ç¨ ä»
jdk21å¯ç¨ |
| | | virtual: |
| | | enabled: false |
| | | # èµæºä¿¡æ¯ |
| | | messages: |
| | | # å½é
åèµæºæä»¶è·¯å¾ |
| | |
| | | # 设置æ»ä¸ä¼ çæä»¶å¤§å° |
| | | max-request-size: 20MB |
| | | mvc: |
| | | # 设置éæèµæºè·¯å¾ 鲿¢ææè¯·æ±é½å»æ¥éæèµæº |
| | | static-path-pattern: /static/** |
| | | format: |
| | | date-time: yyyy-MM-dd HH:mm:ss |
| | | jackson: |
| | |
| | | # MyBatisPlusé
ç½® |
| | | # https://baomidou.com/config/ |
| | | mybatis-plus: |
| | | # 䏿¯æå¤å
, 妿éè¦å¯å¨æ³¨è§£é
ç½® æ æåæ«å
ç级 |
| | | # ä¾å¦ com.**.**.mapper |
| | | # å¤å
åä½¿ç¨ ä¾å¦ org.dromara.**.mapper,org.xxx.**.mapper |
| | | mapperPackage: org.dromara.**.mapper |
| | | # 对åºç XML æä»¶ä½ç½® |
| | | mapperLocations: classpath*:mapper/**/*Mapper.xml |
| | |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # å
¨å±çº¿ç¨æ± ç¸å
³é
ç½® |
| | | # å¦ä½¿ç¨JDK21è¯·ç´æ¥ä½¿ç¨èæçº¿ç¨ ä¸è¦å¼å¯æ¤é
ç½® |
| | | thread-pool: |
| | | # æ¯å¦å¼å¯çº¿ç¨æ± |
| | | enabled: false |
| | |
| | | path: /resource/websocket |
| | | # è®¾ç½®è®¿é®æºå°å |
| | | allowedOrigins: '*' |
| | | |
| | | --- #flowableé
ç½® |
| | | flowable: |
| | | async-executor-activate: false #å
³é宿¶ä»»å¡JOB |
| | | # å°databaseSchemaUpdate设置为trueãå½Flowableåç°åºä¸æ°æ®åºè¡¨ç»æä¸ä¸è´æ¶ï¼ä¼èªå¨å°æ°æ®åºè¡¨ç»æåçº§è³æ°çæ¬ã |
| | | database-schema-update: true |
| | | activity-font-name: å®ä½ |
| | | label-font-name: å®ä½ |
| | | annotation-font-name: å®ä½ |
| | | # å
³éå个模åçæè¡¨ï¼ç®ååªä½¿ç¨å·¥ä½æµåºç¡è¡¨ |
| | | idm: |
| | | enabled: false |
| | | cmmn: |
| | | enabled: false |
| | | dmn: |
| | | enabled: false |
| | | app: |
| | | enabled: false |
| | |
| | | </description> |
| | | |
| | | <properties> |
| | | <revision>5.1.2</revision> |
| | | <revision>5.2.0-BETA</revision> |
| | | </properties> |
| | | |
| | | <dependencyManagement> |
| | |
| | | <artifactId>ip2region</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.EnableAspectJAutoProxy; |
| | | import org.springframework.scheduling.annotation.EnableAsync; |
| | | |
| | | /** |
| | | * ç¨åºæ³¨è§£é
ç½® |
| | |
| | | @AutoConfiguration |
| | | // 表示éè¿aopæ¡æ¶æ´é²è¯¥ä»£ç对象,AopContextè½å¤è®¿é® |
| | | @EnableAspectJAutoProxy(exposeProxy = true) |
| | | @EnableAsync(proxyTargetClass = true) |
| | | public class ApplicationConfig { |
| | | |
| | | } |
| | |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.core.task.VirtualThreadTaskExecutor; |
| | | import org.springframework.scheduling.annotation.AsyncConfigurer; |
| | | import org.springframework.scheduling.annotation.EnableAsync; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.concurrent.Executor; |
| | | |
| | | /** |
| | | * 弿¥é
ç½® |
| | | * <p> |
| | | * 妿æªä½¿ç¨èæçº¿ç¨åçæ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @EnableAsync(proxyTargetClass = true) |
| | | @AutoConfiguration |
| | | public class AsyncConfig implements AsyncConfigurer { |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public Executor getAsyncExecutor() { |
| | | if(SpringUtils.isVirtual()) { |
| | | return new VirtualThreadTaskExecutor("async-"); |
| | | } |
| | | return SpringUtils.getBean("scheduledExecutorService"); |
| | | } |
| | | |
| | |
| | | String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d"; |
| | | |
| | | /** |
| | | * 客æ·ç«¯ |
| | | */ |
| | | String SYS_CLIENT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_client#30d"; |
| | | |
| | | /** |
| | | * ç¨æ·è´¦æ· |
| | | */ |
| | | String SYS_USER_NAME = "sys_user_name#30d"; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.constant; |
| | | |
| | | import cn.hutool.core.lang.RegexPool; |
| | | |
| | | /** |
| | | * å¸¸ç¨æ£å表达å¼å符串 |
| | | * <p> |
| | | * å¸¸ç¨æ£å表达å¼éåï¼æ´å¤æ£åè§: https://any86.github.io/any-rule/ |
| | | * |
| | | * @author Feng |
| | | */ |
| | | public interface RegexConstants extends RegexPool { |
| | | |
| | | /** |
| | | * åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼ |
| | | */ |
| | | String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$"; |
| | | |
| | | /** |
| | | * æéæ è¯å¿
须符å tool:build:list æ ¼å¼ï¼æè
空å符串 |
| | | */ |
| | | String PERMISSION_STRING = "^(|^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+:[a-zA-Z0-9_]+)$"; |
| | | |
| | | /** |
| | | * 身份è¯å·ç ï¼å6ä½ï¼ |
| | | */ |
| | | String ID_CARD_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; |
| | | |
| | | /** |
| | | * QQå·ç |
| | | */ |
| | | String QQ_NUMBER = "^[1-9][0-9]\\d{4,9}$"; |
| | | |
| | | /** |
| | | * 鮿¿ç¼ç |
| | | */ |
| | | String POSTAL_CODE = "^[1-9]\\d{5}$"; |
| | | |
| | | /** |
| | | * 注åè´¦å· |
| | | */ |
| | | String ACCOUNT = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"; |
| | | |
| | | /** |
| | | * å¯ç ï¼å
å«è³å°8个å符ï¼å
æ¬å¤§å忝ãå°ååæ¯ãæ°ååç¹æ®å符 |
| | | */ |
| | | String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; |
| | | |
| | | /** |
| | | * éç¨ç¶æï¼0表示æ£å¸¸ï¼1表示åç¨ï¼ |
| | | */ |
| | | String STATUS = "^[01]$"; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.domain.dto; |
| | | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * OSS对象 |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class OssDTO implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 对象åå¨ä¸»é® |
| | | */ |
| | | private Long ossId; |
| | | |
| | | /** |
| | | * æä»¶å |
| | | */ |
| | | private String fileName; |
| | | |
| | | /** |
| | | * åå |
| | | */ |
| | | private String originalName; |
| | | |
| | | /** |
| | | * æä»¶åç¼å |
| | | */ |
| | | private String fileSuffix; |
| | | |
| | | /** |
| | | * URLå°å |
| | | */ |
| | | private String url; |
| | | |
| | | } |
| | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | |
| | | @NoArgsConstructor |
| | | public class RoleDTO implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * è§è²ID |
| | | */ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.domain.dto; |
| | | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * ç¨æ· |
| | | * |
| | | * @author Michelle.Chung |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class UserDTO implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¨æ·ID |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç¨æ·è´¦å· |
| | | */ |
| | | private String userName; |
| | | |
| | | /** |
| | | * ç¨æ·æµç§° |
| | | */ |
| | | private String nickName; |
| | | |
| | | /** |
| | | * ç¨æ·ç±»åï¼sys_userç³»ç»ç¨æ·ï¼ |
| | | */ |
| | | private String userType; |
| | | |
| | | /** |
| | | * ç¨æ·é®ç®± |
| | | */ |
| | | private String email; |
| | | |
| | | /** |
| | | * ææºå·ç |
| | | */ |
| | | private String phonenumber; |
| | | |
| | | /** |
| | | * ç¨æ·æ§å«ï¼0ç· 1女 2æªç¥ï¼ |
| | | */ |
| | | private String sex; |
| | | |
| | | /** |
| | | * å¸å·ç¶æï¼0æ£å¸¸ 1åç¨ï¼ |
| | | */ |
| | | private String status; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | |
| | | } |
| | |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class LoginUser implements Serializable { |
| | |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * é¨é¨ç±»å«ç¼ç |
| | | */ |
| | | private String deptCategory; |
| | | |
| | | /** |
| | | * é¨é¨å |
| | | */ |
| | | private String deptName; |
| | |
| | | package org.dromara.common.core.exception; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.*; |
| | | |
| | | import java.io.Serial; |
| | | |
| | |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getDetailMessage() { |
| | | return detailMessage; |
| | | } |
| | | |
| | | @Override |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public ServiceException setMessage(String message) { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.factory; |
| | | |
| | | import cn.hutool.core.lang.PatternPool; |
| | | import org.dromara.common.core.constant.RegexConstants; |
| | | |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * æ£åè¡¨è¾¾å¼æ¨¡å¼æ± å·¥å |
| | | * <p>åå§åçæ¶åå°æ£å表达å¼å å
¥ç¼åæ± å½ä¸</p> |
| | | * <p>æé«æ£å表达å¼çæ§è½ï¼é¿å
éå¤ç¼è¯ç¸åçæ£å表达å¼</p> |
| | | * |
| | | * @author 21001 |
| | | */ |
| | | public class RegexPatternPoolFactory extends PatternPool { |
| | | |
| | | /** |
| | | * åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼ |
| | | */ |
| | | public static final Pattern DICTIONARY_TYPE = get(RegexConstants.DICTIONARY_TYPE); |
| | | |
| | | /** |
| | | * 身份è¯å·ç ï¼å6ä½ï¼ |
| | | */ |
| | | public static final Pattern ID_CARD_LAST_6 = get(RegexConstants.ID_CARD_LAST_6); |
| | | |
| | | /** |
| | | * QQå·ç |
| | | */ |
| | | public static final Pattern QQ_NUMBER = get(RegexConstants.QQ_NUMBER); |
| | | |
| | | /** |
| | | * 鮿¿ç¼ç |
| | | */ |
| | | public static final Pattern POSTAL_CODE = get(RegexConstants.POSTAL_CODE); |
| | | |
| | | /** |
| | | * 注åè´¦å· |
| | | */ |
| | | public static final Pattern ACCOUNT = get(RegexConstants.ACCOUNT); |
| | | |
| | | /** |
| | | * å¯ç ï¼å
å«è³å°8个å符ï¼å
æ¬å¤§å忝ãå°ååæ¯ãæ°ååç¹æ®å符 |
| | | */ |
| | | public static final Pattern PASSWORD = get(RegexConstants.PASSWORD); |
| | | |
| | | /** |
| | | * éç¨ç¶æï¼0表示æ£å¸¸ï¼1表示åç¨ï¼ |
| | | */ |
| | | public static final Pattern STATUS = get(RegexConstants.STATUS); |
| | | |
| | | } |
| | |
| | | package org.dromara.common.core.service; |
| | | |
| | | import org.dromara.common.core.domain.dto.OssDTO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éç¨ OSSæå¡ |
| | | * |
| | |
| | | */ |
| | | String selectUrlByIds(String ossIds); |
| | | |
| | | /** |
| | | * éè¿ossIdæ¥è¯¢å表 |
| | | * |
| | | * @param ossIds ossId串éå·åé |
| | | * @return å表 |
| | | */ |
| | | List<OssDTO> selectByIds(String ossIds); |
| | | } |
| | |
| | | package org.dromara.common.core.service; |
| | | |
| | | import org.dromara.common.core.domain.dto.UserDTO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éç¨ ç¨æ·æå¡ |
| | | * |
| | |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·è´¦æ· |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return ç¨æ·è´¦æ· |
| | | * @return ç¨æ·åç§° |
| | | */ |
| | | String selectNicknameById(Long userId); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·è´¦æ· |
| | | * |
| | | * @param userIds ç¨æ·ID å¤ä¸ªç¨éå·éå¼ |
| | | * @return ç¨æ·åç§° |
| | | */ |
| | | String selectNicknameByIds(String userIds); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·ææºå· |
| | | * |
| | | * @param userId ç¨æ·id |
| | | * @return ç¨æ·ææºå· |
| | | */ |
| | | String selectPhonenumberById(Long userId); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·é®ç®± |
| | | * |
| | | * @param userId ç¨æ·id |
| | | * @return ç¨æ·é®ç®± |
| | | */ |
| | | String selectEmailById(Long userId); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·å表 |
| | | * |
| | | * @param userIds ç¨æ·ids |
| | | * @return ç¨æ·å表 |
| | | */ |
| | | List<UserDTO> selectListByIds(List<Long> userIds); |
| | | |
| | | /** |
| | | * éè¿è§è²IDæ¥è¯¢ç¨æ·ID |
| | | * |
| | | * @param roleIds è§è²ids |
| | | * @return ç¨æ·ids |
| | | */ |
| | | List<Long> selectUserIdsByRoleIds(List<Long> roleIds); |
| | | } |
| | |
| | | import cn.hutool.extra.spring.SpringUtil; |
| | | import org.springframework.aop.framework.AopContext; |
| | | import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
| | | import org.springframework.boot.autoconfigure.thread.Threading; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.core.env.Environment; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | |
| | | return getApplicationContext(); |
| | | } |
| | | |
| | | public static boolean isVirtual() { |
| | | return Threading.VIRTUAL.isActive(getBean(Environment.class)); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | public static final String SEPARATOR = ","; |
| | | |
| | | public static final String SLASH = "/"; |
| | | |
| | | /** |
| | | * è·ååæ°ä¸ä¸ºç©ºå¼ |
| | | * |
| | |
| | | package org.dromara.common.core.utils; |
| | | |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import jakarta.validation.ConstraintViolation; |
| | | import jakarta.validation.ConstraintViolationException; |
| | | import jakarta.validation.Validator; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | |
| | | |
| | | private static final Validator VALID = SpringUtils.getBean(Validator.class); |
| | | |
| | | /** |
| | | * 对ç»å®å¯¹è±¡è¿è¡åæ°æ ¡éªï¼å¹¶æ ¹æ®æå®çæ ¡éªç»è¿è¡æ ¡éª |
| | | * |
| | | * @param object è¦è¿è¡æ ¡éªç对象 |
| | | * @param groups æ ¡éªç» |
| | | * @throws ConstraintViolationException å¦ææ ¡éªä¸éè¿ï¼åæåºåæ°æ ¡éªå¼å¸¸ |
| | | */ |
| | | public static <T> void validate(T object, Class<?>... groups) { |
| | | Set<ConstraintViolation<T>> validate = VALID.validate(object, groups); |
| | | if (!validate.isEmpty()) { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.utils.regex; |
| | | |
| | | |
| | | import cn.hutool.core.util.ReUtil; |
| | | import org.dromara.common.core.constant.RegexConstants; |
| | | |
| | | /** |
| | | * æ£åç¸å
³å·¥å
·ç±» |
| | | * |
| | | * @author Feng |
| | | */ |
| | | public final class RegexUtils extends ReUtil { |
| | | |
| | | /** |
| | | * ä»è¾å
¥åç¬¦ä¸²ä¸æåå¹é
çé¨åï¼å¦ææ²¡æå¹é
åè¿åé»è®¤å¼ |
| | | * |
| | | * @param input è¦æåçè¾å
¥å符串 |
| | | * @param regex ç¨äºå¹é
çæ£å表达å¼ï¼å¯ä»¥ä½¿ç¨ {@link RegexConstants} ä¸å®ä¹ç常é |
| | | * @param defaultInput å¦ææ²¡æå¹é
æ¶è¿åçé»è®¤å¼ |
| | | * @return 妿æ¾å°å¹é
çé¨åï¼åè¿åå¹é
çé¨åï¼å¦åè¿åé»è®¤å¼ |
| | | */ |
| | | public static String extractFromString(String input, String regex, String defaultInput) { |
| | | try { |
| | | return ReUtil.get(regex, input, 1); |
| | | } catch (Exception e) { |
| | | return defaultInput; |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.core.utils.regex; |
| | | |
| | | import cn.hutool.core.exceptions.ValidateException; |
| | | import cn.hutool.core.lang.Validator; |
| | | import org.dromara.common.core.factory.RegexPatternPoolFactory; |
| | | |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * æ£ååæ®µæ ¡éªå¨ |
| | | * 主è¦éªè¯å段éç©ºãæ¯å¦ä¸ºæ»¡è¶³æå®æ ¼å¼ç |
| | | * |
| | | * @author Feng |
| | | */ |
| | | public class RegexValidator extends Validator { |
| | | |
| | | /** |
| | | * åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼ |
| | | */ |
| | | public static final Pattern DICTIONARY_TYPE = RegexPatternPoolFactory.DICTIONARY_TYPE; |
| | | |
| | | /** |
| | | * 身份è¯å·ç ï¼å6ä½ï¼ |
| | | */ |
| | | public static final Pattern ID_CARD_LAST_6 = RegexPatternPoolFactory.ID_CARD_LAST_6; |
| | | |
| | | /** |
| | | * QQå·ç |
| | | */ |
| | | public static final Pattern QQ_NUMBER = RegexPatternPoolFactory.QQ_NUMBER; |
| | | |
| | | /** |
| | | * 鮿¿ç¼ç |
| | | */ |
| | | public static final Pattern POSTAL_CODE = RegexPatternPoolFactory.POSTAL_CODE; |
| | | |
| | | /** |
| | | * 注åè´¦å· |
| | | */ |
| | | public static final Pattern ACCOUNT = RegexPatternPoolFactory.ACCOUNT; |
| | | |
| | | /** |
| | | * å¯ç ï¼å
å«è³å°8个å符ï¼å
æ¬å¤§å忝ãå°ååæ¯ãæ°ååç¹æ®å符 |
| | | */ |
| | | public static final Pattern PASSWORD = RegexPatternPoolFactory.PASSWORD; |
| | | |
| | | /** |
| | | * éç¨ç¶æï¼0表示æ£å¸¸ï¼1表示åç¨ï¼ |
| | | */ |
| | | public static final Pattern STATUS = RegexPatternPoolFactory.STATUS; |
| | | |
| | | |
| | | /** |
| | | * æ£æ¥è¾å
¥çè´¦å·æ¯å¦å¹é
é¢å®ä¹çè§å |
| | | * |
| | | * @param value è¦éªè¯çè´¦å· |
| | | * @return å¦æè´¦å·ç¬¦åè§åï¼è¿å trueï¼å¦åï¼è¿å falseã |
| | | */ |
| | | public static boolean isAccount(CharSequence value) { |
| | | return isMatchRegex(ACCOUNT, value); |
| | | } |
| | | |
| | | /** |
| | | * éªè¯è¾å
¥çè´¦å·æ¯å¦ç¬¦åè§åï¼å¦æä¸ç¬¦åï¼åæåº ValidateException å¼å¸¸ |
| | | * |
| | | * @param value è¦éªè¯çè´¦å· |
| | | * @param errorMsg éªè¯å¤±è´¥æ¶æåºçå¼å¸¸æ¶æ¯ |
| | | * @param <T> CharSequence çåç±»å |
| | | * @return 妿éªè¯éè¿ï¼è¿åè¾å
¥çè´¦å· |
| | | * @throws ValidateException 妿éªè¯å¤±è´¥ |
| | | */ |
| | | public static <T extends CharSequence> T validateAccount(T value, String errorMsg) throws ValidateException { |
| | | if (!isAccount(value)) { |
| | | throw new ValidateException(errorMsg); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥è¾å
¥çç¶ææ¯å¦å¹é
é¢å®ä¹çè§å |
| | | * |
| | | * @param value è¦éªè¯çç¶æ |
| | | * @return å¦æç¶æç¬¦åè§åï¼è¿å trueï¼å¦åï¼è¿å falseã |
| | | */ |
| | | public static boolean isStatus(CharSequence value) { |
| | | return isMatchRegex(STATUS, value); |
| | | } |
| | | |
| | | /** |
| | | * éªè¯è¾å
¥çç¶ææ¯å¦ç¬¦åè§åï¼å¦æä¸ç¬¦åï¼åæåº ValidateException å¼å¸¸ |
| | | * |
| | | * @param value è¦éªè¯çç¶æ |
| | | * @param errorMsg éªè¯å¤±è´¥æ¶æåºçå¼å¸¸æ¶æ¯ |
| | | * @param <T> CharSequence çåç±»å |
| | | * @return 妿éªè¯éè¿ï¼è¿åè¾å
¥çç¶æ |
| | | * @throws ValidateException 妿éªè¯å¤±è´¥ |
| | | */ |
| | | public static <T extends CharSequence> T validateStatus(T value, String errorMsg) throws ValidateException { |
| | | if (!isStatus(value)) { |
| | | throw new ValidateException(errorMsg); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | } |
| | |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.bouncycastle</groupId> |
| | | <artifactId>bcprov-jdk15to18</artifactId> |
| | | </dependency> |
| | |
| | | <artifactId>spring-webmvc</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-spring-boot3-starter</artifactId> |
| | | <optional>true</optional> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.mybatis</groupId> |
| | | <artifactId>mybatis-spring</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | package org.dromara.common.encrypt.config; |
| | | |
| | | import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; |
| | | import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.encrypt.core.EncryptorManager; |
| | | import org.dromara.common.encrypt.interceptor.MybatisDecryptInterceptor; |
| | | import org.dromara.common.encrypt.interceptor.MybatisEncryptInterceptor; |
| | |
| | | * @author è马 |
| | | * @version 4.6.0 |
| | | */ |
| | | @AutoConfiguration |
| | | @AutoConfiguration(after = MybatisPlusAutoConfiguration.class) |
| | | @EnableConfigurationProperties(EncryptorProperties.class) |
| | | @ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true") |
| | | @Slf4j |
| | | public class EncryptorAutoConfiguration { |
| | | |
| | | @Autowired |
| | | private EncryptorProperties properties; |
| | | |
| | | @Bean |
| | | public EncryptorManager encryptorManager() { |
| | | return new EncryptorManager(); |
| | | public EncryptorManager encryptorManager(MybatisPlusProperties mybatisPlusProperties) { |
| | | return new EncryptorManager(mybatisPlusProperties.getTypeAliasesPackage()); |
| | | } |
| | | |
| | | @Bean |
| | |
| | | public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) { |
| | | return new MybatisDecryptInterceptor(encryptorManager, properties); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | package org.dromara.common.encrypt.core; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.io.Resources; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.encrypt.annotation.EncryptField; |
| | | import org.springframework.context.ConfigurableApplicationContext; |
| | | import org.springframework.core.io.Resource; |
| | | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
| | | import org.springframework.core.io.support.ResourcePatternResolver; |
| | | import org.springframework.core.type.ClassMetadata; |
| | | import org.springframework.core.type.classreading.CachingMetadataReaderFactory; |
| | | import org.springframework.util.ClassUtils; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.Arrays; |
| | | import java.util.HashSet; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | * @version 4.6.0 |
| | | */ |
| | | @Slf4j |
| | | @NoArgsConstructor |
| | | public class EncryptorManager { |
| | | |
| | | /** |
| | |
| | | Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * æé æ¹æ³ä¼ å
¥ç±»å å¯å段ç¼å |
| | | * |
| | | * @param typeAliasesPackage å®ä½ç±»å
|
| | | */ |
| | | public EncryptorManager(String typeAliasesPackage) { |
| | | scanEncryptClasses(typeAliasesPackage); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åç±»å å¯å段ç¼å |
| | | */ |
| | | public Set<Field> getFieldCache(Class<?> sourceClazz) { |
| | | return fieldCache.computeIfAbsent(sourceClazz, clazz -> { |
| | | Set<Field> fieldSet = new HashSet<>(); |
| | | while (clazz != null) { |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | fieldSet.addAll(Arrays.asList(fields)); |
| | | clazz = clazz.getSuperclass(); |
| | | } |
| | | fieldSet = fieldSet.stream().filter(field -> |
| | | field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class) |
| | | .collect(Collectors.toSet()); |
| | | for (Field field : fieldSet) { |
| | | field.setAccessible(true); |
| | | } |
| | | return fieldSet; |
| | | }); |
| | | if (ObjectUtil.isNotNull(fieldCache)) { |
| | | return fieldCache.get(sourceClazz); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | |
| | | return encryptor.decrypt(value); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ typeAliasesPackage è®¾ç½®çæ«æå
æ«æç¼åå®ä½ |
| | | */ |
| | | private void scanEncryptClasses(String typeAliasesPackage) { |
| | | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); |
| | | CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory(); |
| | | String[] packagePatternArray = StringUtils.splitPreserveAllTokens(typeAliasesPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); |
| | | String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX; |
| | | try { |
| | | for (String packagePattern : packagePatternArray) { |
| | | String path = ClassUtils.convertClassNameToResourcePath(packagePattern); |
| | | Resource[] resources = resolver.getResources(classpath + path + "/*.class"); |
| | | for (Resource resource : resources) { |
| | | ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata(); |
| | | Class<?> clazz = Resources.classForName(classMetadata.getClassName()); |
| | | Set<Field> encryptFieldSet = getEncryptFieldSetFromClazz(clazz); |
| | | if (CollUtil.isNotEmpty(encryptFieldSet)) { |
| | | fieldCache.put(clazz, encryptFieldSet); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("åå§åæ°æ®å®å
¨ç¼åæ¶åºé:{}", e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å¾ä¸ä¸ªç±»çå å¯å段éå |
| | | */ |
| | | private Set<Field> getEncryptFieldSetFromClazz(Class<?> clazz) { |
| | | Set<Field> fieldSet = new HashSet<>(); |
| | | // 夿clazzå¦ææ¯æ¥å£,å
é¨ç±»,å¿åç±»å°±ç´æ¥è¿å |
| | | if (clazz.isInterface() || clazz.isMemberClass() || clazz.isAnonymousClass()) { |
| | | return fieldSet; |
| | | } |
| | | while (clazz != null) { |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | fieldSet.addAll(Arrays.asList(fields)); |
| | | clazz = clazz.getSuperclass(); |
| | | } |
| | | fieldSet = fieldSet.stream().filter(field -> |
| | | field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class) |
| | | .collect(Collectors.toSet()); |
| | | for (Field field : fieldSet) { |
| | | field.setAccessible(true); |
| | | } |
| | | return fieldSet; |
| | | } |
| | | |
| | | } |
| | |
| | | import org.dromara.common.encrypt.annotation.ApiEncrypt; |
| | | import org.dromara.common.encrypt.properties.ApiDecryptProperties; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.method.HandlerMethod; |
| | | import org.springframework.web.servlet.HandlerExceptionResolver; |
| | | import org.springframework.web.servlet.HandlerExecutionChain; |
| | | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | |
| | | |
| | | /** |
| | |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| | | HttpServletRequest servletRequest = (HttpServletRequest) request; |
| | | HttpServletResponse servletResponse = (HttpServletResponse) response; |
| | | |
| | | boolean responseFlag = false; |
| | | // è·åå 坿³¨è§£ |
| | | ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); |
| | | boolean responseFlag = apiEncrypt != null && apiEncrypt.response(); |
| | | ServletRequest requestWrapper = null; |
| | | ServletResponse responseWrapper = null; |
| | | EncryptResponseBodyWrapper responseBodyWrapper = null; |
| | | |
| | | // æ¯å¦ä¸º json è¯·æ± |
| | | if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { |
| | | // æ¯å¦ä¸º put æè
post è¯·æ± |
| | | if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { |
| | | // æ¯å¦åå¨å 坿 头 |
| | | String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); |
| | | // è·åå 坿³¨è§£ |
| | | ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); |
| | | responseFlag = apiEncrypt != null && apiEncrypt.response(); |
| | | if (StringUtils.isNotBlank(headerValue)) { |
| | | // 请æ±è§£å¯ |
| | | requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); |
| | | } else { |
| | | // æ¯å¦ææ³¨è§£ï¼æå°±æ¥éï¼æ²¡ææ¾è¡ |
| | | if (ObjectUtil.isNotNull(apiEncrypt)) { |
| | | HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); |
| | | exceptionResolver.resolveException( |
| | | servletRequest, servletResponse, null, |
| | | new ServiceException("没æè®¿é®æéï¼è¯·è系管çåææ", HttpStatus.FORBIDDEN)); |
| | | return; |
| | | } |
| | | } |
| | | // 夿æ¯å¦ååºå å¯ |
| | | if (responseFlag) { |
| | | responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); |
| | | responseWrapper = responseBodyWrapper; |
| | | // æ¯å¦ä¸º put æè
post è¯·æ± |
| | | if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { |
| | | // æ¯å¦åå¨å 坿 头 |
| | | String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); |
| | | if (StringUtils.isNotBlank(headerValue)) { |
| | | // 请æ±è§£å¯ |
| | | requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); |
| | | } else { |
| | | // æ¯å¦ææ³¨è§£ï¼æå°±æ¥éï¼æ²¡ææ¾è¡ |
| | | if (ObjectUtil.isNotNull(apiEncrypt)) { |
| | | HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); |
| | | exceptionResolver.resolveException( |
| | | servletRequest, servletResponse, null, |
| | | new ServiceException("没æè®¿é®æéï¼è¯·è系管çåææ", HttpStatus.FORBIDDEN)); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 夿æ¯å¦ååºå å¯ |
| | | if (responseFlag) { |
| | | responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); |
| | | responseWrapper = responseBodyWrapper; |
| | | } |
| | | |
| | | chain.doFilter( |
| | | ObjectUtil.defaultIfNull(requestWrapper, request), |
| | | ObjectUtil.defaultIfNull(responseWrapper, response)); |
| | |
| | | String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); |
| | | |
| | | // 设置ååºå¤´ |
| | | servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag); |
| | | servletResponse.setHeader(headerFlag, encryptPassword); |
| | | servletResponse.setHeader("Access-Control-Allow-Origin", "*"); |
| | | servletResponse.setHeader("Access-Control-Allow-Methods", "*"); |
| | |
| | | list.forEach(this::decryptHandler); |
| | | return; |
| | | } |
| | | // ä¸å¨ç¼åä¸çç±»,å°±æ¯æ²¡æå 坿³¨è§£çç±»(å½ç¶ä¹æå¯è½æ¯typeAliasesPackageåé) |
| | | Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass()); |
| | | if(ObjectUtil.isNull(fields)){ |
| | | return; |
| | | } |
| | | try { |
| | | for (Field field : fields) { |
| | | field.set(sourceObject, this.decryptField(Convert.toStr(field.get(sourceObject)), field)); |
| | |
| | | list.forEach(this::encryptHandler); |
| | | return; |
| | | } |
| | | // ä¸å¨ç¼åä¸çç±»,å°±æ¯æ²¡æå 坿³¨è§£çç±»(å½ç¶ä¹æå¯è½æ¯typeAliasesPackageåé) |
| | | Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass()); |
| | | if(ObjectUtil.isNull(fields)){ |
| | | return; |
| | | } |
| | | try { |
| | | for (Field field : fields) { |
| | | field.set(sourceObject, this.encryptField(Convert.toStr(field.get(sourceObject)), field)); |
| | |
| | | */ |
| | | int index() default -1; |
| | | |
| | | /** |
| | | * åå¹¶éè¦ä¾èµçå
¶ä»å段åç§° |
| | | */ |
| | | String[] mergeBy() default {}; |
| | | |
| | | } |
| | |
| | | package org.dromara.common.excel.core; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.alibaba.excel.metadata.Head; |
| | | import com.alibaba.excel.write.handler.WorkbookWriteHandler; |
| | | import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; |
| | | import com.alibaba.excel.write.merge.AbstractMergeStrategy; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | |
| | | import org.dromara.common.excel.annotation.CellMerge; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * åå¼éå¤åå¹¶çç¥ |
| | |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | public class CellMergeStrategy extends AbstractMergeStrategy { |
| | | public class CellMergeStrategy extends AbstractMergeStrategy implements WorkbookWriteHandler { |
| | | |
| | | private final List<CellRangeAddress> cellList; |
| | | private final boolean hasTitle; |
| | |
| | | |
| | | @Override |
| | | protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { |
| | | // judge the list is not null |
| | | if (CollUtil.isNotEmpty(cellList)) { |
| | | // the judge is necessary |
| | | if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == 0) { |
| | | for (CellRangeAddress item : cellList) { |
| | | sheet.addMergedRegion(item); |
| | | //åå
æ ¼åå
¥äº,éååå¹¶åºå,å¦æè¯¥Cellå¨åºåå
,ä½éé¦è¡,忏
空 |
| | | final int rowIndex = cell.getRowIndex(); |
| | | if (CollUtil.isNotEmpty(cellList)){ |
| | | for (CellRangeAddress cellAddresses : cellList) { |
| | | final int firstRow = cellAddresses.getFirstRow(); |
| | | if (cellAddresses.isInRange(cell) && rowIndex != firstRow){ |
| | | cell.setBlank(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void afterWorkbookDispose(final WorkbookWriteHandlerContext context) { |
| | | //å½åè¡¨æ ¼åå®åï¼ç»ä¸åå
¥ |
| | | if (CollUtil.isNotEmpty(cellList)){ |
| | | for (CellRangeAddress item : cellList) { |
| | | context.getWriteContext().writeSheetHolder().getSheet().addMergedRegion(item); |
| | | } |
| | | } |
| | | } |
| | |
| | | // 空å¼è·³è¿ä¸åå¹¶ |
| | | continue; |
| | | } |
| | | |
| | | if (!cellValue.equals(val)) { |
| | | if (i - repeatCell.getCurrent() > 1) { |
| | | if ((i - repeatCell.getCurrent() > 1) && isMerge(list, i, field)) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); |
| | | } |
| | | map.put(field, new RepeatCell(val, i)); |
| | | } else if (j == 0) { |
| | | if (i == list.size() - 1) { |
| | | if (i > repeatCell.getCurrent()) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); |
| | | } |
| | | } |
| | | } else { |
| | | // 夿åé¢çæ¯å¦åå¹¶äº |
| | | RepeatCell firstCell = map.get(mergeFields.get(0)); |
| | | if (repeatCell.getCurrent() != firstCell.getCurrent()) { |
| | | if (i == list.size() - 1) { |
| | | if (i > repeatCell.getCurrent()) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); |
| | | } |
| | | } else if (repeatCell.getCurrent() < firstCell.getCurrent()) { |
| | | if (i - repeatCell.getCurrent() > 1) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); |
| | | } |
| | | map.put(field, new RepeatCell(val, i)); |
| | | } |
| | | } else if (i == list.size() - 1) { |
| | | if (i > repeatCell.getCurrent()) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); |
| | | } |
| | | } else if (i == list.size() - 1) { |
| | | if (i > repeatCell.getCurrent() && isMerge(list, i, field)) { |
| | | cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); |
| | | } |
| | | } |
| | | } |
| | |
| | | return cellList; |
| | | } |
| | | |
| | | private boolean isMerge(List<?> list, int i, Field field) { |
| | | boolean isMerge = true; |
| | | CellMerge cm = field.getAnnotation(CellMerge.class); |
| | | final String[] mergeBy = cm.mergeBy(); |
| | | if (StrUtil.isAllNotBlank(mergeBy)) { |
| | | //æ¯å¯¹å½ålist(i)ålist(i - 1)çåä¸ªå±æ§å¼ä¸ä¸æ¯å¯¹ 妿å
¨ä¸ºç å为ç |
| | | for (String fieldName : mergeBy) { |
| | | final Object valCurrent = ReflectUtil.getFieldValue(list.get(i), fieldName); |
| | | final Object valPre = ReflectUtil.getFieldValue(list.get(i - 1), fieldName); |
| | | if (!Objects.equals(valPre, valCurrent)) { |
| | | //ä¾èµåæ®µå¦æä»»ä¸ä¸çå¼,åæ è®°ä¸ºä¸å¯åå¹¶ |
| | | isMerge = false; |
| | | } |
| | | } |
| | | } |
| | | return isMerge; |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | static class RepeatCell { |
| | |
| | | import org.dromara.common.core.service.DictService; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.excel.annotation.ExcelDictFormat; |
| | | import org.dromara.common.excel.annotation.ExcelEnumFormat; |
| | | |
| | |
| | | ExcelDictFormat format = field.getDeclaredAnnotation(ExcelDictFormat.class); |
| | | String dictType = format.dictType(); |
| | | String converterExp = format.readConverterExp(); |
| | | if (StrUtil.isNotBlank(dictType)) { |
| | | if (StringUtils.isNotBlank(dictType)) { |
| | | // å¦æä¼ éäºåå
¸åï¼å便®åå
¸å»ºç«ä¸æ |
| | | Collection<String> values = Optional.ofNullable(dictService.getAllDictByDictType(dictType)) |
| | | .orElseThrow(() -> new ServiceException(String.format("åå
¸ %s ä¸åå¨", dictType))) |
| | | .values(); |
| | | options = new ArrayList<>(values); |
| | | } else if (StrUtil.isNotBlank(converterExp)) { |
| | | } else if (StringUtils.isNotBlank(converterExp)) { |
| | | // 妿æå®äºç¡®åçå¼ï¼åç´æ¥è§£æç¡®åçå¼ |
| | | options = StrUtil.split(converterExp, format.separator(), true, true); |
| | | List<String> strList = StringUtils.splitList(converterExp, format.separator()); |
| | | options = StreamUtils.toList(strList, s -> StringUtils.split(s, "=")[1]); |
| | | } |
| | | } else if (field.isAnnotationPresent(ExcelEnumFormat.class)) { |
| | | // å¦å妿æå®äº@ExcelEnumFormatï¼åä½¿ç¨æä¸¾çé»è¾ |
| | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.springframework.validation.BindingResult; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | |
| | | public boolean isFilterObject(final Object o) { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); |
| | | } else if (Collection.class.isAssignableFrom(clazz)) { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) { |
| | |
| | | <artifactId>spring-boot-autoconfigure</artifactId> |
| | | </dependency> |
| | | |
| | | <!--PowerJob--> |
| | | <!-- SnailJob client --> |
| | | <dependency> |
| | | <groupId>tech.powerjob</groupId> |
| | | <artifactId>powerjob-worker-spring-boot-starter</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>powerjob-remote-impl-akka</artifactId> |
| | | <groupId>tech.powerjob</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-starter</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>tech.powerjob</groupId> |
| | | <artifactId>powerjob-official-processors</artifactId> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-client-job-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.job.config; |
| | | |
| | | import ch.qos.logback.classic.Logger; |
| | | import ch.qos.logback.classic.LoggerContext; |
| | | import ch.qos.logback.classic.spi.ILoggingEvent; |
| | | import com.aizuda.snailjob.client.common.appender.SnailLogbackAppender; |
| | | import com.aizuda.snailjob.client.common.event.SnailClientStartingEvent; |
| | | import com.aizuda.snailjob.client.starter.EnableSnailJob; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.scheduling.annotation.EnableScheduling; |
| | | |
| | | /** |
| | | * å¯å¨å®æ¶ä»»å¡ |
| | | * |
| | | * @author opensnail |
| | | * @date 2024-05-17 |
| | | */ |
| | | @AutoConfiguration |
| | | @ConditionalOnProperty(prefix = "snail-job", name = "enabled", havingValue = "true") |
| | | @EnableScheduling |
| | | @EnableSnailJob(group = "${snail-job.group-name}") |
| | | public class SnailJobConfig { |
| | | |
| | | @EventListener(SnailClientStartingEvent.class) |
| | | public void onStarting(SnailClientStartingEvent event) { |
| | | LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); |
| | | SnailLogbackAppender<ILoggingEvent> ca = new SnailLogbackAppender<>(); |
| | | ca.setName("snail_log_appender"); |
| | | ca.start(); |
| | | Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME); |
| | | rootLogger.addAppender(ca); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | org.dromara.common.job.config.SnailJobConfig |
| | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.exc.MismatchedInputException; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | |
| | | return OBJECT_MAPPER; |
| | | } |
| | | |
| | | /** |
| | | * å°å¯¹è±¡è½¬æ¢ä¸ºJSONæ ¼å¼çå符串 |
| | | * |
| | | * @param object è¦è½¬æ¢ç对象 |
| | | * @return JSONæ ¼å¼çå符串ï¼å¦æå¯¹è±¡ä¸ºnullï¼åè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçJSONå¤çå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static String toJsonString(Object object) { |
| | | if (ObjectUtil.isNull(object)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°JSONæ ¼å¼çå符串转æ¢ä¸ºæå®ç±»åç对象 |
| | | * |
| | | * @param text JSONæ ¼å¼çå符串 |
| | | * @param clazz è¦è½¬æ¢çç®æ 对象类å |
| | | * @param <T> ç®æ å¯¹è±¡çæ³åç±»å |
| | | * @return 转æ¢åç对象ï¼å¦æå符串为空åè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static <T> T parseObject(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°åèæ°ç»è½¬æ¢ä¸ºæå®ç±»åç对象 |
| | | * |
| | | * @param bytes åèæ°ç» |
| | | * @param clazz è¦è½¬æ¢çç®æ 对象类å |
| | | * @param <T> ç®æ å¯¹è±¡çæ³åç±»å |
| | | * @return 转æ¢åç对象ï¼å¦æåèæ°ç»ä¸ºç©ºåè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static <T> T parseObject(byte[] bytes, Class<T> clazz) { |
| | | if (ArrayUtil.isEmpty(bytes)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°JSONæ ¼å¼çå符串转æ¢ä¸ºæå®ç±»åçå¯¹è±¡ï¼æ¯æå¤æç±»å |
| | | * |
| | | * @param text JSONæ ¼å¼çå符串 |
| | | * @param typeReference æå®ç±»åçTypeReference对象 |
| | | * @param <T> ç®æ å¯¹è±¡çæ³åç±»å |
| | | * @return 转æ¢åç对象ï¼å¦æå符串为空åè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static <T> T parseObject(String text, TypeReference<T> typeReference) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°JSONæ ¼å¼çå符串转æ¢ä¸ºDict对象 |
| | | * |
| | | * @param text JSONæ ¼å¼çå符串 |
| | | * @return 转æ¢åçDict对象ï¼å¦æå符串为空æè
䏿¯JSONæ ¼å¼åè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static Dict parseMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°JSONæ ¼å¼çå符串转æ¢ä¸ºDict对象çå表 |
| | | * |
| | | * @param text JSONæ ¼å¼çå符串 |
| | | * @return 转æ¢åçDict对象çå表ï¼å¦æå符串为空åè¿ånull |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static List<Dict> parseArrayMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°JSONæ ¼å¼çå符串转æ¢ä¸ºæå®ç±»å对象çå表 |
| | | * |
| | | * @param text JSONæ ¼å¼çå符串 |
| | | * @param clazz è¦è½¬æ¢çç®æ 对象类å |
| | | * @param <T> ç®æ å¯¹è±¡çæ³åç±»å |
| | | * @return 转æ¢åç对象çå表ï¼å¦æå符串为空åè¿å空å表 |
| | | * @throws RuntimeException å¦æè½¬æ¢è¿ç¨ä¸åçIOå¼å¸¸ï¼åæåºè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | public static <T> List<T> parseArray(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | | return new ArrayList<>(); |
| | |
| | | <artifactId>ruoyi-common-json</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.alibaba.ttl.TransmittableThreadLocal; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessStatus; |
| | | import org.dromara.common.log.event.OperLogEvent; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessStatus; |
| | | import org.dromara.common.log.event.OperLogEvent; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.validation.BindingResult; |
| | |
| | | |
| | | |
| | | /** |
| | | * è®¡ç®æä½æ¶èæ¶é´ |
| | | * è®¡æ¶ key |
| | | */ |
| | | private static final ThreadLocal<StopWatch> TIME_THREADLOCAL = new TransmittableThreadLocal<>(); |
| | | private static final ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>(); |
| | | |
| | | /** |
| | | * å¤ç请æ±åæ§è¡ |
| | |
| | | @Before(value = "@annotation(controllerLog)") |
| | | public void boBefore(JoinPoint joinPoint, Log controllerLog) { |
| | | StopWatch stopWatch = new StopWatch(); |
| | | TIME_THREADLOCAL.set(stopWatch); |
| | | KEY_CACHE.set(stopWatch); |
| | | stopWatch.start(); |
| | | } |
| | | |
| | |
| | | // å¤ç设置注解ä¸çåæ° |
| | | getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); |
| | | // 设置æ¶èæ¶é´ |
| | | StopWatch stopWatch = TIME_THREADLOCAL.get(); |
| | | StopWatch stopWatch = KEY_CACHE.get(); |
| | | stopWatch.stop(); |
| | | operLog.setCostTime(stopWatch.getTime()); |
| | | // åå¸äºä»¶ä¿åæ°æ®åº |
| | |
| | | log.error("å¼å¸¸ä¿¡æ¯:{}", exp.getMessage()); |
| | | exp.printStackTrace(); |
| | | } finally { |
| | | TIME_THREADLOCAL.remove(); |
| | | KEY_CACHE.remove(); |
| | | } |
| | | } |
| | | |
| | |
| | | public boolean isFilterObject(final Object o) { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); |
| | | } else if (Collection.class.isAssignableFrom(clazz)) { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) { |
| | |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.mybatis</groupId> |
| | | <artifactId>mybatis-spring</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | <artifactId>mybatis-plus-spring-boot3-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- sqlæ§è½åææä»¶ --> |
| | |
| | | package org.dromara.common.mybatis.config; |
| | | |
| | | import cn.hutool.core.net.NetUtil; |
| | | import com.baomidou.mybatisplus.autoconfigure.DdlApplicationRunner; |
| | | import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; |
| | | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
| | | import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.extension.ddl.IDdl; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; |
| | | import org.dromara.common.core.factory.YmlPropertySourceFactory; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.mybatis.handler.InjectionMetaObjectHandler; |
| | | import org.dromara.common.mybatis.handler.MybatisExceptionHandler; |
| | | import org.dromara.common.mybatis.interceptor.PlusDataPermissionInterceptor; |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.PropertySource; |
| | | import org.springframework.transaction.annotation.EnableTransactionManagement; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * mybatis-plusé
置类(䏿¹æ³¨éææä»¶ä»ç») |
| | |
| | | * @author Lion Li |
| | | */ |
| | | @EnableTransactionManagement(proxyTargetClass = true) |
| | | @AutoConfiguration(before = MybatisPlusAutoConfiguration.class) |
| | | @MapperScan("${mybatis-plus.mapperPackage}") |
| | | @PropertySource(value = "classpath:common-mybatis.yml", factory = YmlPropertySourceFactory.class) |
| | | public class MybatisPlusConfig { |
| | |
| | | @Bean |
| | | public MybatisPlusInterceptor mybatisPlusInterceptor() { |
| | | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| | | // å¤ç§æ·æä»¶ å¿
é¡»æ¾å°ç¬¬ä¸ä½ |
| | | try { |
| | | TenantLineInnerInterceptor tenant = SpringUtils.getBean(TenantLineInnerInterceptor.class); |
| | | interceptor.addInnerInterceptor(tenant); |
| | | } catch (BeansException ignore) { |
| | | } |
| | | // æ°æ®æéå¤ç |
| | | interceptor.addInnerInterceptor(dataPermissionInterceptor()); |
| | | // å页æä»¶ |
| | |
| | | * æ°æ®æéæ¦æªå¨ |
| | | */ |
| | | public PlusDataPermissionInterceptor dataPermissionInterceptor() { |
| | | return new PlusDataPermissionInterceptor(); |
| | | return new PlusDataPermissionInterceptor(SpringUtils.getProperty("mybatis-plus.mapperPackage")); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public PaginationInnerInterceptor paginationInnerInterceptor() { |
| | | PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
| | | // 设置æå¤§å页éå¶æ°éï¼é»è®¤ 500 æ¡ï¼-1 ä¸åéå¶ |
| | | paginationInnerInterceptor.setMaxLimit(-1L); |
| | | // å页åçå |
| | | paginationInnerInterceptor.setOverflow(true); |
| | | return paginationInnerInterceptor; |
| | |
| | | } |
| | | |
| | | /** |
| | | * å¼å¸¸å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public MybatisExceptionHandler mybatisExceptionHandler() { |
| | | return new MybatisExceptionHandler(); |
| | | } |
| | | |
| | | /** |
| | | * PaginationInnerInterceptor å页æä»¶ï¼èªå¨è¯å«æ°æ®åºç±»å |
| | | * https://baomidou.com/pages/97710a/ |
| | | * OptimisticLockerInnerInterceptor ä¹è§éæä»¶ |
| | |
| | | * DynamicTableNameInnerInterceptor å¨æè¡¨åæä»¶ |
| | | * https://baomidou.com/pages/2a45ff/ |
| | | */ |
| | | |
| | | @Bean |
| | | public DdlApplicationRunner ddlApplicationRunner(@Autowired(required = false) List<IDdl> ddlList) { |
| | | return new DdlApplicationRunner(ddlList); |
| | | } |
| | | |
| | | } |
| | |
| | | Log log = LogFactory.getLog(BaseMapperPlus.class); |
| | | |
| | | default Class<V> currentVoClass() { |
| | | GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class); |
| | | return (Class<V>) GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class)[1]; |
| | | } |
| | | |
| | |
| | | return selectVoOne(wrapper, this.currentVoClass()); |
| | | } |
| | | |
| | | default V selectVoOne(Wrapper<T> wrapper, boolean throwEx) { |
| | | return selectVoOne(wrapper, this.currentVoClass(), throwEx); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢ä¸æ¡è®°å½ |
| | | */ |
| | | default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) { |
| | | T obj = this.selectOne(wrapper); |
| | | return selectVoOne(wrapper, voClass, true); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® entity æ¡ä»¶ï¼æ¥è¯¢ä¸æ¡è®°å½ |
| | | */ |
| | | default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass, boolean throwEx) { |
| | | T obj = this.selectOne(wrapper, throwEx); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | return null; |
| | | } |
| | |
| | | return list; |
| | | } |
| | | |
| | | public Integer getFirstNum() { |
| | | return (pageNum - 1) * pageSize; |
| | | } |
| | | |
| | | } |
| | |
| | | ? baseEntity.getCreateTime() : new Date(); |
| | | baseEntity.setCreateTime(current); |
| | | baseEntity.setUpdateTime(current); |
| | | LoginUser loginUser = getLoginUser(); |
| | | if (ObjectUtil.isNotNull(loginUser)) { |
| | | Long userId = ObjectUtil.isNotNull(baseEntity.getCreateBy()) |
| | | ? baseEntity.getCreateBy() : loginUser.getUserId(); |
| | | // å½åå·²ç»å½ ä¸ å建人为空 åå¡«å
|
| | | baseEntity.setCreateBy(userId); |
| | | // å½åå·²ç»å½ ä¸ æ´æ°äººä¸ºç©º åå¡«å
|
| | | baseEntity.setUpdateBy(userId); |
| | | baseEntity.setCreateDept(ObjectUtil.isNotNull(baseEntity.getCreateDept()) |
| | | ? baseEntity.getCreateDept() : loginUser.getDeptId()); |
| | | if (ObjectUtil.isNull(baseEntity.getCreateBy())) { |
| | | LoginUser loginUser = getLoginUser(); |
| | | if (ObjectUtil.isNotNull(loginUser)) { |
| | | Long userId = loginUser.getUserId(); |
| | | // å½åå·²ç»å½ ä¸ å建人为空 åå¡«å
|
| | | baseEntity.setCreateBy(userId); |
| | | // å½åå·²ç»å½ ä¸ æ´æ°äººä¸ºç©º åå¡«å
|
| | | baseEntity.setUpdateBy(userId); |
| | | baseEntity.setCreateDept(ObjectUtil.isNotNull(baseEntity.getCreateDept()) |
| | | ? baseEntity.getCreateDept() : loginUser.getDeptId()); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | |
| | | Date current = new Date(); |
| | | // æ´æ°æ¶é´å¡«å
(ä¸ç®¡ä¸ºä¸ä¸ºç©º) |
| | | baseEntity.setUpdateTime(current); |
| | | LoginUser loginUser = getLoginUser(); |
| | | // å½åå·²ç»å½ æ´æ°äººå¡«å
(ä¸ç®¡ä¸ºä¸ä¸ºç©º) |
| | | if (ObjectUtil.isNotNull(loginUser)) { |
| | | baseEntity.setUpdateBy(loginUser.getUserId()); |
| | | Long userId = LoginHelper.getUserId(); |
| | | if (ObjectUtil.isNotNull(userId)) { |
| | | baseEntity.setUpdateBy(userId); |
| | | } |
| | | |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException("èªå¨æ³¨å
¥å¼å¸¸ => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED); |
| | |
| | | |
| | | import org.dromara.common.core.domain.R; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.mybatis.spring.MyBatisSystemException; |
| | | import org.springframework.dao.DuplicateKeyException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | |
| | | public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | String message = e.getMessage(); |
| | | if ("CannotFindDataSourceException".contains(message)) { |
| | | if (StringUtils.contains("CannotFindDataSourceException", message)) { |
| | | log.error("请æ±å°å'{}', æªæ¾å°æ°æ®æº", requestURI); |
| | | return R.fail("æªæ¾å°æ°æ®æºï¼è¯·è系管çå确认"); |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.annotation.AnnotationUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ClassUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import net.sf.jsqlparser.JSQLParserException; |
| | |
| | | import net.sf.jsqlparser.expression.Parenthesis; |
| | | import net.sf.jsqlparser.expression.operators.conditional.AndExpression; |
| | | import net.sf.jsqlparser.parser.CCJSqlParserUtil; |
| | | import org.apache.ibatis.io.Resources; |
| | | import org.dromara.common.core.domain.dto.RoleDTO; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | |
| | | import org.dromara.common.mybatis.enums.DataScopeType; |
| | | import org.dromara.common.mybatis.helper.DataPermissionHelper; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.springframework.context.ConfigurableApplicationContext; |
| | | import org.springframework.context.expression.BeanFactoryResolver; |
| | | import org.springframework.core.io.Resource; |
| | | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
| | | import org.springframework.core.io.support.ResourcePatternResolver; |
| | | import org.springframework.core.type.ClassMetadata; |
| | | import org.springframework.core.type.classreading.CachingMetadataReaderFactory; |
| | | import org.springframework.expression.BeanResolver; |
| | | import org.springframework.expression.ExpressionParser; |
| | | import org.springframework.expression.ParserContext; |
| | | import org.springframework.expression.common.TemplateParserContext; |
| | | import org.springframework.expression.spel.standard.SpelExpressionParser; |
| | | import org.springframework.expression.spel.support.StandardEvaluationContext; |
| | | import org.springframework.util.ClassUtils; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.*; |
| | | import java.util.Arrays; |
| | | import java.util.HashSet; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.function.Function; |
| | | |
| | |
| | | */ |
| | | private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory()); |
| | | |
| | | public PlusDataPermissionHandler(String mapperPackage) { |
| | | scanMapperClasses(mapperPackage); |
| | | } |
| | | |
| | | |
| | | public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) { |
| | | DataColumn[] dataColumns = findAnnotation(mappedStatementId); |
| | | DataPermission dataPermission = getDataPermission(mappedStatementId); |
| | | LoginUser currentUser = DataPermissionHelper.getVariable("user"); |
| | | if (ObjectUtil.isNull(currentUser)) { |
| | | currentUser = LoginHelper.getLoginUser(); |
| | |
| | | if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) { |
| | | return where; |
| | | } |
| | | String dataFilterSql = buildDataFilter(dataColumns, isSelect); |
| | | String dataFilterSql = buildDataFilter(dataPermission.value(), isSelect); |
| | | if (StringUtils.isBlank(dataFilterSql)) { |
| | | return where; |
| | | } |
| | |
| | | return ""; |
| | | } |
| | | |
| | | public DataColumn[] findAnnotation(String mappedStatementId) { |
| | | StringBuilder sb = new StringBuilder(mappedStatementId); |
| | | int index = sb.lastIndexOf("."); |
| | | String clazzName = sb.substring(0, index); |
| | | String methodName = sb.substring(index + 1, sb.length()); |
| | | Class<?> clazz; |
| | | /** |
| | | * éè¿ mapperPackage è®¾ç½®çæ«æå
æ«æç¼åææ³¨è§£çæ¹æ³ä¸ç±» |
| | | */ |
| | | private void scanMapperClasses(String mapperPackage) { |
| | | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); |
| | | CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory(); |
| | | String[] packagePatternArray = StringUtils.splitPreserveAllTokens(mapperPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); |
| | | String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX; |
| | | try { |
| | | clazz = ClassUtil.loadClass(clazzName); |
| | | for (String packagePattern : packagePatternArray) { |
| | | String path = ClassUtils.convertClassNameToResourcePath(packagePattern); |
| | | Resource[] resources = resolver.getResources(classpath + path + "/*.class"); |
| | | for (Resource resource : resources) { |
| | | ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata(); |
| | | Class<?> clazz = Resources.classForName(classMetadata.getClassName()); |
| | | findAnnotation(clazz); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | return null; |
| | | log.error("åå§åæ°æ®å®å
¨ç¼åæ¶åºé:{}", e.getMessage()); |
| | | } |
| | | List<Method> methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz)) |
| | | .filter(method -> method.getName().equals(methodName)).toList(); |
| | | } |
| | | |
| | | private void findAnnotation(Class<?> clazz) { |
| | | DataPermission dataPermission; |
| | | // è·åæ¹æ³æ³¨è§£ |
| | | for (Method method : methods) { |
| | | dataPermission = dataPermissionCacheMap.get(mappedStatementId); |
| | | if (ObjectUtil.isNotNull(dataPermission)) { |
| | | return dataPermission.value(); |
| | | for (Method method : clazz.getMethods()) { |
| | | if (method.isDefault() || method.isVarArgs()) { |
| | | continue; |
| | | } |
| | | String mappedStatementId = clazz.getName() + "." + method.getName(); |
| | | if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) { |
| | | dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class); |
| | | dataPermissionCacheMap.put(mappedStatementId, dataPermission); |
| | | return dataPermission.value(); |
| | | } |
| | | } |
| | | dataPermission = dataPermissionCacheMap.get(clazz.getName()); |
| | | if (ObjectUtil.isNotNull(dataPermission)) { |
| | | return dataPermission.value(); |
| | | } |
| | | // è·å类注解 |
| | | if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) { |
| | | dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class); |
| | | dataPermissionCacheMap.put(clazz.getName(), dataPermission); |
| | | return dataPermission.value(); |
| | | } |
| | | } |
| | | |
| | | public DataPermission getDataPermission(String mapperId) { |
| | | if (dataPermissionCacheMap.containsKey(mapperId)) { |
| | | return dataPermissionCacheMap.get(mapperId); |
| | | } |
| | | String clazzName = mapperId.substring(0, mapperId.lastIndexOf(".")); |
| | | if (dataPermissionCacheMap.containsKey(clazzName)) { |
| | | return dataPermissionCacheMap.get(clazzName); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦æ æ |
| | | */ |
| | | public boolean invalid(String mapperId) { |
| | | return getDataPermission(mapperId) == null; |
| | | } |
| | | } |
| | |
| | | package org.dromara.common.mybatis.interceptor; |
| | | |
| | | import cn.hutool.core.collection.ConcurrentHashSet; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; |
| | | import com.baomidou.mybatisplus.core.toolkit.PluginUtils; |
| | | import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; |
| | | import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.BaseMultiTableInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; |
| | | import org.dromara.common.mybatis.annotation.DataColumn; |
| | | import org.dromara.common.mybatis.handler.PlusDataPermissionHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import net.sf.jsqlparser.schema.Table; |
| | | import net.sf.jsqlparser.statement.delete.Delete; |
| | | import net.sf.jsqlparser.statement.select.PlainSelect; |
| | | import net.sf.jsqlparser.statement.select.Select; |
| | | import net.sf.jsqlparser.statement.select.SelectBody; |
| | | import net.sf.jsqlparser.statement.select.SetOperationList; |
| | | import net.sf.jsqlparser.statement.update.Update; |
| | | import org.apache.ibatis.executor.Executor; |
| | |
| | | import org.apache.ibatis.mapping.SqlCommandType; |
| | | import org.apache.ibatis.session.ResultHandler; |
| | | import org.apache.ibatis.session.RowBounds; |
| | | import org.dromara.common.mybatis.handler.PlusDataPermissionHandler; |
| | | |
| | | import java.sql.Connection; |
| | | import java.sql.SQLException; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * æ°æ®æéæ¦æªå¨ |
| | |
| | | * @author Lion Li |
| | | * @version 3.5.0 |
| | | */ |
| | | public class PlusDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor { |
| | | @Slf4j |
| | | public class PlusDataPermissionInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor { |
| | | |
| | | private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler(); |
| | | /** |
| | | * æ ææ³¨è§£æ¹æ³ç¼åç¨äºå¿«éè¿å |
| | | */ |
| | | private final Set<String> invalidCacheSet = new ConcurrentHashSet<>(); |
| | | private final PlusDataPermissionHandler dataPermissionHandler; |
| | | |
| | | public PlusDataPermissionInterceptor(String mapperPackage) { |
| | | this.dataPermissionHandler = new PlusDataPermissionHandler(mapperPackage); |
| | | } |
| | | |
| | | @Override |
| | | public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { |
| | |
| | | return; |
| | | } |
| | | // æ£æ¥æ¯å¦æ æ æ æ°æ®æé注解 |
| | | if (invalidCacheSet.contains(ms.getId())) { |
| | | return; |
| | | } |
| | | DataColumn[] dataColumns = dataPermissionHandler.findAnnotation(ms.getId()); |
| | | if (ArrayUtil.isEmpty(dataColumns)) { |
| | | invalidCacheSet.add(ms.getId()); |
| | | if (dataPermissionHandler.invalid(ms.getId())) { |
| | | return; |
| | | } |
| | | // è§£æ sql åé
å¯¹åºæ¹æ³ |
| | |
| | | return; |
| | | } |
| | | // æ£æ¥æ¯å¦æ æ æ æ°æ®æé注解 |
| | | if (invalidCacheSet.contains(ms.getId())) { |
| | | return; |
| | | } |
| | | DataColumn[] dataColumns = dataPermissionHandler.findAnnotation(ms.getId()); |
| | | if (ArrayUtil.isEmpty(dataColumns)) { |
| | | invalidCacheSet.add(ms.getId()); |
| | | if (dataPermissionHandler.invalid(ms.getId())) { |
| | | return; |
| | | } |
| | | PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); |
| | |
| | | |
| | | @Override |
| | | protected void processSelect(Select select, int index, String sql, Object obj) { |
| | | SelectBody selectBody = select.getSelectBody(); |
| | | if (selectBody instanceof PlainSelect plainSelect) { |
| | | this.setWhere(plainSelect, (String) obj); |
| | | } else if (selectBody instanceof SetOperationList setOperationList) { |
| | | List<SelectBody> selectBodyList = setOperationList.getSelects(); |
| | | if (select instanceof PlainSelect) { |
| | | this.setWhere((PlainSelect) select, (String) obj); |
| | | } else if (select instanceof SetOperationList setOperationList) { |
| | | List<Select> selectBodyList = setOperationList.getSelects(); |
| | | selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj)); |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Expression buildTableExpression(Table table, Expression where, String whereSegment) { |
| | | // åªææ°çæ°æ®æéå¤ç卿伿§è¡å°è¿é |
| | | final MultiDataPermissionHandler handler = (MultiDataPermissionHandler) dataPermissionHandler; |
| | | return handler.getSqlSegment(table, where, whereSegment); |
| | | } |
| | | } |
| | | |
ÎļþÃû´Ó ruoyi-admin/src/main/resources/spy.properties ÐÞ¸Ä |
| | |
| | | appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger |
| | | # ä½¿ç¨æ¥å¿ç³»ç»è®°å½ sql |
| | | #appender=com.p6spy.engine.spy.appender.Slf4JLogger |
| | | # 设置 p6spy driver 代ç |
| | | #deregisterdrivers=true |
| | | # åæ¶JDBC URLåç¼ |
| | | useprefix=true |
| | | # é
ç½®è®°å½ Log ä¾å¤,å¯å»æçç»æéæerror,info,batch,debug,statement,commit,rollback,result,resultset. |
| | |
| | | dateformat=yyyy-MM-dd HH:mm:ss |
| | | # SQLè¯å¥æå°æ¶é´æ ¼å¼ |
| | | databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss |
| | | # å®é
驱å¨å¯å¤ä¸ª |
| | | #driverlist=org.h2.Driver |
| | | # æ¯å¦å¼å¯æ
¢SQLè®°å½ |
| | | outagedetection=true |
| | | # æ
¢SQLè®°å½æ å 2 ç§ |
| | | outagedetectioninterval=2 |
| | | # æ¯å¦è¿æ»¤ Log |
| | | filter=true |
| | | # è¿æ»¤ Log æ¶ææé¤ç sql å
³é®åï¼ä»¥éå·åé |
| | |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- AWS SDK for Java 2.x --> |
| | | <dependency> |
| | | <groupId>com.amazonaws</groupId> |
| | | <artifactId>aws-java-sdk-s3</artifactId> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>s3</artifactId> |
| | | <exclusions> |
| | | <!-- å°åºäº Netty ç HTTP 客æ·ç«¯ä»ç±»è·¯å¾ä¸ç§»é¤ --> |
| | | <exclusion> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>netty-nio-client</artifactId> |
| | | </exclusion> |
| | | <!-- å°åºäº CRT ç HTTP 客æ·ç«¯ä»ç±»è·¯å¾ä¸ç§»é¤ --> |
| | | <exclusion> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>aws-crt-client</artifactId> |
| | | </exclusion> |
| | | <!-- å°åºäº Apache ç HTTP 客æ·ç«¯ä»ç±»è·¯å¾ä¸ç§»é¤ --> |
| | | <exclusion> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>apache-client</artifactId> |
| | | </exclusion> |
| | | <!-- å°é
ç½®åºäº URL è¿æ¥ç HTTP 客æ·ç«¯ä»ç±»è·¯å¾ä¸ç§»é¤ --> |
| | | <exclusion> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>url-connection-client</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <!-- 使ç¨AWSåºäº CRT ç S3 客æ·ç«¯ --> |
| | | <dependency> |
| | | <groupId>software.amazon.awssdk.crt</groupId> |
| | | <artifactId>aws-crt</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- åºäº AWS CRT ç S3 客æ·ç«¯çæ§è½å¢å¼ºç S3 ä¼ è¾ç®¡çå¨ --> |
| | | <dependency> |
| | | <groupId>software.amazon.awssdk</groupId> |
| | | <artifactId>s3-transfer-manager</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.amazonaws.ClientConfiguration; |
| | | import com.amazonaws.HttpMethod; |
| | | import com.amazonaws.Protocol; |
| | | import com.amazonaws.auth.AWSCredentials; |
| | | import com.amazonaws.auth.AWSCredentialsProvider; |
| | | import com.amazonaws.auth.AWSStaticCredentialsProvider; |
| | | import com.amazonaws.auth.BasicAWSCredentials; |
| | | import com.amazonaws.client.builder.AwsClientBuilder; |
| | | import com.amazonaws.services.s3.AmazonS3; |
| | | import com.amazonaws.services.s3.AmazonS3Client; |
| | | import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
| | | import com.amazonaws.services.s3.model.*; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.common.core.utils.DateUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.core.utils.file.FileUtils; |
| | | import org.dromara.common.oss.constant.OssConstant; |
| | | import org.dromara.common.oss.entity.UploadResult; |
| | | import org.dromara.common.oss.enumd.AccessPolicyType; |
| | | import org.dromara.common.oss.enumd.PolicyType; |
| | | import org.dromara.common.oss.exception.OssException; |
| | | import org.dromara.common.oss.properties.OssProperties; |
| | | import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; |
| | | import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; |
| | | import software.amazon.awssdk.core.ResponseInputStream; |
| | | import software.amazon.awssdk.core.async.AsyncRequestBody; |
| | | import software.amazon.awssdk.core.async.AsyncResponseTransformer; |
| | | import software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody; |
| | | import software.amazon.awssdk.regions.Region; |
| | | import software.amazon.awssdk.services.s3.S3AsyncClient; |
| | | import software.amazon.awssdk.services.s3.S3Configuration; |
| | | import software.amazon.awssdk.services.s3.model.GetObjectResponse; |
| | | import software.amazon.awssdk.services.s3.model.NoSuchBucketException; |
| | | import software.amazon.awssdk.services.s3.model.S3Exception; |
| | | import software.amazon.awssdk.services.s3.presigner.S3Presigner; |
| | | import software.amazon.awssdk.transfer.s3.S3TransferManager; |
| | | import software.amazon.awssdk.transfer.s3.model.*; |
| | | import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.File; |
| | | import java.io.InputStream; |
| | | import java.io.*; |
| | | import java.net.URI; |
| | | import java.net.URL; |
| | | import java.util.Date; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.time.Duration; |
| | | |
| | | /** |
| | | * S3 åå¨åè®® ææå
¼å®¹S3åè®®çäºåå忝æ |
| | | * é¿éäº è
¾è®¯äº ä¸çäº minio |
| | | * |
| | | * @author Lion Li |
| | | * @author AprilWind |
| | | */ |
| | | public class OssClient { |
| | | |
| | | /** |
| | | * æå¡å |
| | | */ |
| | | private final String configKey; |
| | | |
| | | /** |
| | | * é
ç½®å±æ§ |
| | | */ |
| | | private final OssProperties properties; |
| | | |
| | | private final AmazonS3 client; |
| | | /** |
| | | * Amazon S3 弿¥å®¢æ·ç«¯ |
| | | */ |
| | | private final S3AsyncClient client; |
| | | |
| | | /** |
| | | * ç¨äºç®¡ç S3 æ°æ®ä¼ è¾çé«çº§å·¥å
· |
| | | */ |
| | | private final S3TransferManager transferManager; |
| | | |
| | | /** |
| | | * AWS S3 é¢ç¾å URL ççæå¨ |
| | | */ |
| | | private final S3Presigner presigner; |
| | | |
| | | /** |
| | | * æé æ¹æ³ |
| | | * |
| | | * @param configKey é
ç½®é® |
| | | * @param ossProperties Ossé
ç½®å±æ§ |
| | | */ |
| | | public OssClient(String configKey, OssProperties ossProperties) { |
| | | this.configKey = configKey; |
| | | this.properties = ossProperties; |
| | | try { |
| | | AwsClientBuilder.EndpointConfiguration endpointConfig = |
| | | new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion()); |
| | | // å建 AWS 认è¯ä¿¡æ¯ |
| | | StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( |
| | | AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey())); |
| | | |
| | | AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey()); |
| | | AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); |
| | | ClientConfiguration clientConfig = new ClientConfiguration(); |
| | | if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { |
| | | clientConfig.setProtocol(Protocol.HTTPS); |
| | | } else { |
| | | clientConfig.setProtocol(Protocol.HTTP); |
| | | } |
| | | AmazonS3ClientBuilder build = AmazonS3Client.builder() |
| | | .withEndpointConfiguration(endpointConfig) |
| | | .withClientConfiguration(clientConfig) |
| | | .withCredentials(credentialsProvider) |
| | | .disableChunkedEncoding(); |
| | | if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) { |
| | | // minio 使ç¨httpséå¶ä½¿ç¨ååè®¿é® éè¦æ¤é
ç½® ç«ç¹å¡«åå |
| | | build.enablePathStyleAccess(); |
| | | } |
| | | this.client = build.build(); |
| | | //MinIO ä½¿ç¨ HTTPS éå¶ä½¿ç¨åå访é®ï¼ç«ç¹å¡«ååãéè¦å¯ç¨è·¯å¾æ ·å¼è®¿é® |
| | | boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE); |
| | | |
| | | //å建AWSåºäº CRT ç S3 客æ·ç«¯ |
| | | this.client = S3AsyncClient.crtBuilder() |
| | | .credentialsProvider(credentialsProvider) |
| | | .endpointOverride(URI.create(getEndpoint())) |
| | | .region(of()) |
| | | .targetThroughputInGbps(20.0) |
| | | .minimumPartSizeInBytes(10 * 1025 * 1024L) |
| | | .checksumValidationEnabled(false) |
| | | .forcePathStyle(isStyle) |
| | | .build(); |
| | | |
| | | //AWSåºäº CRT ç S3 AsyncClient å®ä¾ç¨ä½ S3 ä¼ è¾ç®¡çå¨çåºå±å®¢æ·ç«¯ |
| | | this.transferManager = S3TransferManager.builder().s3Client(this.client).build(); |
| | | |
| | | // å建 S3 é
置对象 |
| | | S3Configuration config = S3Configuration.builder().chunkedEncodingEnabled(false) |
| | | .pathStyleAccessEnabled(isStyle).build(); |
| | | |
| | | // å建 é¢ç¾å URL ççæå¨ å®ä¾ï¼ç¨äºçæ S3 é¢ç¾å URL |
| | | this.presigner = S3Presigner.builder() |
| | | .region(of()) |
| | | .credentialsProvider(credentialsProvider) |
| | | .endpointOverride(URI.create(getDomain())) |
| | | .serviceConfiguration(config) |
| | | .build(); |
| | | |
| | | // å建å卿¡¶ |
| | | createBucket(); |
| | | } catch (Exception e) { |
| | | if (e instanceof OssException) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 忥å建å卿¡¶ |
| | | * 妿å卿¡¶ä¸åå¨ï¼ä¼è¿è¡å建ï¼å¦æå卿¡¶åå¨ï¼ä¸æ§è¡ä»»ä½æä½ |
| | | * |
| | | * @throws OssException å½å建å卿¡¶æ¶åçå¼å¸¸æ¶æåº |
| | | */ |
| | | public void createBucket() { |
| | | String bucketName = properties.getBucketName(); |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | if (client.doesBucketExistV2(bucketName)) { |
| | | return; |
| | | // å°è¯è·åå卿¡¶çä¿¡æ¯ |
| | | client.headBucket( |
| | | x -> x.bucket(bucketName) |
| | | .build()) |
| | | .join(); |
| | | } catch (Exception ex) { |
| | | if (ex.getCause() instanceof NoSuchBucketException) { |
| | | try { |
| | | // å卿¡¶ä¸åå¨ï¼å°è¯å建å卿¡¶ |
| | | client.createBucket( |
| | | x -> x.bucket(bucketName)) |
| | | .join(); |
| | | |
| | | // 设置å卿¡¶ç访é®çç¥ï¼Bucket Policyï¼ |
| | | client.putBucketPolicy( |
| | | x -> x.bucket(bucketName) |
| | | .policy(getPolicy(bucketName, getAccessPolicy().getPolicyType()))) |
| | | .join(); |
| | | } catch (S3Exception e) { |
| | | // å卿¡¶å建æçç¥è®¾ç½®å¤±è´¥ |
| | | throw new OssException("å建Bucket失败, è¯·æ ¸å¯¹é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | } else { |
| | | throw new OssException("夿Bucketæ¯å¦åå¨å¤±è´¥ï¼è¯·æ ¸å¯¹é
置信æ¯:[" + ex.getMessage() + "]"); |
| | | } |
| | | CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); |
| | | AccessPolicyType accessPolicy = getAccessPolicy(); |
| | | createBucketRequest.setCannedAcl(accessPolicy.getAcl()); |
| | | client.createBucket(createBucketRequest); |
| | | client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType())); |
| | | } catch (Exception e) { |
| | | throw new OssException("å建Bucket失败, è¯·æ ¸å¯¹é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | } |
| | | |
| | | public UploadResult upload(byte[] data, String path, String contentType) { |
| | | return upload(new ByteArrayInputStream(data), path, contentType); |
| | | /** |
| | | * ä¸ä¼ æä»¶å° Amazon S3ï¼å¹¶è¿åä¸ä¼ ç»æ |
| | | * |
| | | * @param filePath æ¬å°æä»¶è·¯å¾ |
| | | * @param key å¨ Amazon S3 ä¸çå¯¹è±¡é® |
| | | * @param md5Digest æ¬å°æä»¶ç MD5 åå¸å¼ï¼å¯éï¼ |
| | | * @return UploadResult å
å«ä¸ä¼ åçæä»¶ä¿¡æ¯ |
| | | * @throws OssException 妿ä¸ä¼ å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public UploadResult upload(Path filePath, String key, String md5Digest) { |
| | | try { |
| | | // æå»ºä¸ä¼ 请æ±å¯¹è±¡ |
| | | FileUpload fileUpload = transferManager.uploadFile( |
| | | x -> x.putObjectRequest( |
| | | y -> y.bucket(properties.getBucketName()) |
| | | .key(key) |
| | | .contentMD5(StringUtils.isNotEmpty(md5Digest) ? md5Digest : null) |
| | | .build()) |
| | | .addTransferListener(LoggingTransferListener.create()) |
| | | .source(filePath).build()); |
| | | |
| | | // çå¾
ä¸ä¼ 宿并è·åä¸ä¼ ç»æ |
| | | CompletedFileUpload uploadResult = fileUpload.completionFuture().join(); |
| | | String eTag = uploadResult.response().eTag(); |
| | | |
| | | // æåä¸ä¼ ç»æä¸ç ETagï¼å¹¶æå»ºä¸ä¸ªèªå®ä¹ç UploadResult 对象 |
| | | return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build(); |
| | | } catch (Exception e) { |
| | | // æè·å¼å¸¸å¹¶æåºèªå®ä¹å¼å¸¸ |
| | | throw new OssException("ä¸ä¼ æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } finally { |
| | | // æ 论ä¸ä¼ æ¯å¦æåï¼æç»é½ä¼å é¤ä¸´æ¶æä»¶ |
| | | FileUtils.del(filePath); |
| | | } |
| | | } |
| | | |
| | | public UploadResult upload(InputStream inputStream, String path, String contentType) { |
| | | /** |
| | | * ä¸ä¼ InputStream å° Amazon S3 |
| | | * |
| | | * @param inputStream è¦ä¸ä¼ çè¾å
¥æµ |
| | | * @param key å¨ Amazon S3 ä¸çå¯¹è±¡é® |
| | | * @param length è¾å
¥æµçé¿åº¦ |
| | | * @return UploadResult å
å«ä¸ä¼ åçæä»¶ä¿¡æ¯ |
| | | * @throws OssException 妿ä¸ä¼ å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public UploadResult upload(InputStream inputStream, String key, Long length) { |
| | | // 妿è¾å
¥æµä¸æ¯ ByteArrayInputStreamï¼åå°å
¶è¯»å为åèæ°ç»åå建 ByteArrayInputStream |
| | | if (!(inputStream instanceof ByteArrayInputStream)) { |
| | | inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream)); |
| | | } |
| | | try { |
| | | ObjectMetadata metadata = new ObjectMetadata(); |
| | | metadata.setContentType(contentType); |
| | | metadata.setContentLength(inputStream.available()); |
| | | PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata); |
| | | // 设置ä¸ä¼ 对象ç Acl 为å
Œ
±è¯» |
| | | putObjectRequest.setCannedAcl(getAccessPolicy().getAcl()); |
| | | client.putObject(putObjectRequest); |
| | | // åå»ºå¼æ¥è¯·æ±ä½ï¼lengthå¦æä¸ºç©ºä¼æ¥éï¼ |
| | | BlockingInputStreamAsyncRequestBody body = AsyncRequestBody.forBlockingInputStream(length); |
| | | |
| | | // ä½¿ç¨ transferManager è¿è¡ä¸ä¼ |
| | | Upload upload = transferManager.upload( |
| | | x -> x.requestBody(body) |
| | | .putObjectRequest( |
| | | y -> y.bucket(properties.getBucketName()) |
| | | .key(key) |
| | | .build()) |
| | | .build()); |
| | | |
| | | // å°è¾å
¥æµåå
¥è¯·æ±ä½ |
| | | body.writeInputStream(inputStream); |
| | | |
| | | // çå¾
æä»¶ä¸ä¼ æä½å®æ |
| | | CompletedUpload uploadResult = upload.completionFuture().join(); |
| | | String eTag = uploadResult.response().eTag(); |
| | | |
| | | // æåä¸ä¼ ç»æä¸ç ETagï¼å¹¶æå»ºä¸ä¸ªèªå®ä¹ç UploadResult 对象 |
| | | return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build(); |
| | | } catch (Exception e) { |
| | | throw new OssException("ä¸ä¼ æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); |
| | | } |
| | | |
| | | public UploadResult upload(File file, String path) { |
| | | try { |
| | | PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, file); |
| | | // 设置ä¸ä¼ 对象ç Acl 为å
Œ
±è¯» |
| | | putObjectRequest.setCannedAcl(getAccessPolicy().getAcl()); |
| | | client.putObject(putObjectRequest); |
| | | } catch (Exception e) { |
| | | throw new OssException("ä¸ä¼ æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); |
| | | } |
| | | |
| | | public void delete(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | try { |
| | | client.deleteObject(properties.getBucketName(), path); |
| | | } catch (Exception e) { |
| | | throw new OssException("å é¤æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | } |
| | | |
| | | public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { |
| | | return upload(data, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | public UploadResult uploadSuffix(File file, String suffix) { |
| | | return upload(file, getPath(properties.getPrefix(), suffix)); |
| | | } |
| | | |
| | | /** |
| | | * è·åæä»¶å
æ°æ® |
| | | * ä¸è½½æä»¶ä» Amazon S3 å°ä¸´æ¶ç®å½ |
| | | * |
| | | * @param path 宿´æä»¶è·¯å¾ |
| | | * @param path æä»¶å¨ Amazon S3 ä¸çå¯¹è±¡é® |
| | | * @return ä¸è½½åçæä»¶å¨æ¬å°ç临æ¶è·¯å¾ |
| | | * @throws OssException 妿ä¸è½½å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public ObjectMetadata getObjectMetadata(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | S3Object object = client.getObject(properties.getBucketName(), path); |
| | | return object.getObjectMetadata(); |
| | | public Path fileDownload(String path) { |
| | | // æå»ºä¸´æ¶æä»¶ |
| | | Path tempFilePath = FileUtils.createTempFile().toPath(); |
| | | // ä½¿ç¨ S3TransferManager ä¸è½½æä»¶ |
| | | FileDownload downloadFile = transferManager.downloadFile( |
| | | x -> x.getObjectRequest( |
| | | y -> y.bucket(properties.getBucketName()) |
| | | .key(removeBaseUrl(path)) |
| | | .build()) |
| | | .addTransferListener(LoggingTransferListener.create()) |
| | | .destination(tempFilePath) |
| | | .build()); |
| | | // çå¾
æä»¶ä¸è½½æä½å®æ |
| | | downloadFile.completionFuture().join(); |
| | | return tempFilePath; |
| | | } |
| | | |
| | | public InputStream getObjectContent(String path) { |
| | | path = path.replace(getUrl() + "/", ""); |
| | | S3Object object = client.getObject(properties.getBucketName(), path); |
| | | return object.getObjectContent(); |
| | | } |
| | | |
| | | public String getUrl() { |
| | | String domain = properties.getDomain(); |
| | | String endpoint = properties.getEndpoint(); |
| | | String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; |
| | | // äºæå¡åç´æ¥è¿å |
| | | if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { |
| | | if (StringUtils.isNotBlank(domain)) { |
| | | return header + domain; |
| | | /** |
| | | * ä¸è½½æä»¶ä» Amazon S3 å° è¾åºæµ |
| | | * |
| | | * @param key æä»¶å¨ Amazon S3 ä¸çå¯¹è±¡é® |
| | | * @param out è¾åºæµ |
| | | * @return è¾åºæµä¸åå
¥çåèæ°ï¼é¿åº¦ï¼ |
| | | * @throws OssException 妿ä¸è½½å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public long download(String key, OutputStream out) { |
| | | try { |
| | | // æå»ºä¸è½½è¯·æ± |
| | | DownloadRequest<ResponseInputStream<GetObjectResponse>> downloadRequest = DownloadRequest.builder() |
| | | // æä»¶å¯¹è±¡ |
| | | .getObjectRequest(y -> y.bucket(properties.getBucketName()) |
| | | .key(key) |
| | | .build()) |
| | | .addTransferListener(LoggingTransferListener.create()) |
| | | // 使ç¨è®¢é
转æ¢å¨ |
| | | .responseTransformer(AsyncResponseTransformer.toBlockingInputStream()) |
| | | .build(); |
| | | // ä½¿ç¨ S3TransferManager ä¸è½½æä»¶ |
| | | Download<ResponseInputStream<GetObjectResponse>> responseFuture = transferManager.download(downloadRequest); |
| | | // è¾åºå°æµä¸ |
| | | try (ResponseInputStream<GetObjectResponse> responseStream = responseFuture.completionFuture().join().result()) { // auto-closeable stream |
| | | return responseStream.transferTo(out); // é»å¡è°ç¨çº¿ç¨ blocks the calling thread |
| | | } |
| | | return header + properties.getBucketName() + "." + endpoint; |
| | | } catch (Exception e) { |
| | | throw new OssException("æä»¶ä¸è½½å¤±è´¥ï¼é误信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | // minio åç¬å¤ç |
| | | if (StringUtils.isNotBlank(domain)) { |
| | | return header + domain + "/" + properties.getBucketName(); |
| | | } |
| | | return header + endpoint + "/" + properties.getBucketName(); |
| | | } |
| | | |
| | | public String getPath(String prefix, String suffix) { |
| | | // çæuuid |
| | | String uuid = IdUtil.fastSimpleUUID(); |
| | | // æä»¶è·¯å¾ |
| | | String path = DateUtils.datePath() + "/" + uuid; |
| | | if (StringUtils.isNotBlank(prefix)) { |
| | | path = prefix + "/" + path; |
| | | /** |
| | | * å é¤äºå卿å¡ä¸æå®è·¯å¾ä¸æä»¶ |
| | | * |
| | | * @param path æå®è·¯å¾ |
| | | */ |
| | | public void delete(String path) { |
| | | try { |
| | | client.deleteObject( |
| | | x -> x.bucket(properties.getBucketName()) |
| | | .key(removeBaseUrl(path)) |
| | | .build()); |
| | | } catch (Exception e) { |
| | | throw new OssException("å é¤æä»¶å¤±è´¥ï¼è¯·æ£æ¥é
置信æ¯:[" + e.getMessage() + "]"); |
| | | } |
| | | return path + suffix; |
| | | } |
| | | |
| | | |
| | | public String getConfigKey() { |
| | | return configKey; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param second æææ¶é´ |
| | | */ |
| | | public String getPrivateUrl(String objectKey, Integer second) { |
| | | GeneratePresignedUrlRequest generatePresignedUrlRequest = |
| | | new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey) |
| | | .withMethod(HttpMethod.GET) |
| | | .withExpiration(new Date(System.currentTimeMillis() + 1000L * second)); |
| | | URL url = client.generatePresignedUrl(generatePresignedUrlRequest); |
| | | // ä½¿ç¨ AWS S3 é¢ç¾å URL ççæå¨ è·å对象çé¢ç¾å URL |
| | | URL url = presigner.presignGetObject( |
| | | x -> x.signatureDuration(Duration.ofSeconds(second)) |
| | | .getObjectRequest( |
| | | y -> y.bucket(properties.getBucketName()) |
| | | .key(objectKey) |
| | | .build()) |
| | | .build()) |
| | | .url(); |
| | | return url.toString(); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ byte[] æ°æ®å° Amazon S3ï¼ä½¿ç¨æå®çåç¼æé 对象é®ã |
| | | * |
| | | * @param data è¦ä¸ä¼ ç byte[] æ°æ® |
| | | * @param suffix 对象é®çåç¼ |
| | | * @return UploadResult å
å«ä¸ä¼ åçæä»¶ä¿¡æ¯ |
| | | * @throws OssException 妿ä¸ä¼ å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public UploadResult uploadSuffix(byte[] data, String suffix) { |
| | | return upload(new ByteArrayInputStream(data), getPath(properties.getPrefix(), suffix), Long.valueOf(data.length)); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ InputStream å° Amazon S3ï¼ä½¿ç¨æå®çåç¼æé 对象é®ã |
| | | * |
| | | * @param inputStream è¦ä¸ä¼ çè¾å
¥æµ |
| | | * @param suffix 对象é®çåç¼ |
| | | * @param length è¾å
¥æµçé¿åº¦ |
| | | * @return UploadResult å
å«ä¸ä¼ åçæä»¶ä¿¡æ¯ |
| | | * @throws OssException 妿ä¸ä¼ å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, Long length) { |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), length); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ æä»¶å° Amazon S3ï¼ä½¿ç¨æå®çåç¼æé å¯¹è±¡é® |
| | | * |
| | | * @param file è¦ä¸ä¼ çæä»¶ |
| | | * @param suffix 对象é®çåç¼ |
| | | * @return UploadResult å
å«ä¸ä¼ åçæä»¶ä¿¡æ¯ |
| | | * @throws OssException 妿ä¸ä¼ å¤±è´¥ï¼æåºèªå®ä¹å¼å¸¸ |
| | | */ |
| | | public UploadResult uploadSuffix(File file, String suffix) { |
| | | return upload(file.toPath(), getPath(properties.getPrefix(), suffix), null); |
| | | } |
| | | |
| | | /** |
| | | * è·åæä»¶è¾å
¥æµ |
| | | * |
| | | * @param path 宿´æä»¶è·¯å¾ |
| | | * @return è¾å
¥æµ |
| | | */ |
| | | public InputStream getObjectContent(String path) throws IOException { |
| | | // ä¸è½½æä»¶å°ä¸´æ¶ç®å½ |
| | | Path tempFilePath = fileDownload(path); |
| | | // å建è¾å
¥æµ |
| | | InputStream inputStream = Files.newInputStream(tempFilePath); |
| | | // å é¤ä¸´æ¶æä»¶ |
| | | FileUtils.del(tempFilePath); |
| | | // è¿å对象å
容çè¾å
¥æµ |
| | | return inputStream; |
| | | } |
| | | |
| | | /** |
| | | * è·å S3 客æ·ç«¯çç»ç«¯ç¹ URL |
| | | * |
| | | * @return ç»ç«¯ç¹ URL |
| | | */ |
| | | public String getEndpoint() { |
| | | // æ ¹æ®é
ç½®æä»¶ä¸çæ¯å¦ä½¿ç¨ HTTPSï¼è®¾ç½®åè®®å¤´é¨ |
| | | String header = getIsHttps(); |
| | | // æ¼æ¥å议头é¨åç»ç«¯ç¹ï¼å¾å°å®æ´çç»ç«¯ç¹ URL |
| | | return header + properties.getEndpoint(); |
| | | } |
| | | |
| | | /** |
| | | * è·å S3 客æ·ç«¯çç»ç«¯ç¹ URLï¼èªå®ä¹ååï¼ |
| | | * |
| | | * @return ç»ç«¯ç¹ URL |
| | | */ |
| | | public String getDomain() { |
| | | // ä»é
ç½®ä¸è·åååãç»ç«¯ç¹ãæ¯å¦ä½¿ç¨ HTTPS çä¿¡æ¯ |
| | | String domain = properties.getDomain(); |
| | | String endpoint = properties.getEndpoint(); |
| | | String header = getIsHttps(); |
| | | |
| | | // 妿æ¯äºæå¡åï¼ç´æ¥è¿åååæç»ç«¯ç¹ |
| | | if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { |
| | | return StringUtils.isNotEmpty(domain) ? header + domain : header + endpoint; |
| | | } |
| | | |
| | | // å¦ææ¯ MinIOï¼å¤çååå¹¶è¿å |
| | | if (StringUtils.isNotEmpty(domain)) { |
| | | return domain.startsWith(Constants.HTTPS) || domain.startsWith(Constants.HTTP) ? domain : header + domain; |
| | | } |
| | | |
| | | // è¿åç»ç«¯ç¹ |
| | | return header + endpoint; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ä¼ å
¥ç region åæ°è¿åç¸åºç AWS åºå |
| | | * 妿 region åæ°é空ï¼ä½¿ç¨ Region.of æ¹æ³å建并è¿å对åºç AWS åºå对象 |
| | | * 妿 region åæ°ä¸ºç©ºï¼è¿åä¸ä¸ªé»è®¤ç AWS åºåï¼ä¾å¦ï¼us-east-1ï¼ï¼ä½ä¸ºå¹¿æ³æ¯æçåºå |
| | | * |
| | | * @return 对åºç AWS åºåå¯¹è±¡ï¼æè
é»è®¤çå¹¿æ³æ¯æçåºåï¼us-east-1ï¼ |
| | | */ |
| | | public Region of() { |
| | | //AWS åºåå符串 |
| | | String region = properties.getRegion(); |
| | | // 妿 region åæ°é空ï¼ä½¿ç¨ Region.of æ¹æ³å建对åºç AWS åºå对象ï¼å¦åè¿åé»è®¤åºå |
| | | return StringUtils.isNotEmpty(region) ? Region.of(region) : Region.US_EAST_1; |
| | | } |
| | | |
| | | /** |
| | | * è·åäºå卿å¡çURL |
| | | * |
| | | * @return æä»¶è·¯å¾ |
| | | */ |
| | | public String getUrl() { |
| | | String domain = properties.getDomain(); |
| | | String endpoint = properties.getEndpoint(); |
| | | String header = getIsHttps(); |
| | | // äºæå¡åç´æ¥è¿å |
| | | if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { |
| | | return header + (StringUtils.isNotEmpty(domain) ? domain : properties.getBucketName() + "." + endpoint); |
| | | } |
| | | // MinIO åç¬å¤ç |
| | | if (StringUtils.isNotEmpty(domain)) { |
| | | // 妿 domain 以 "https://" æ "http://" å¼å¤´ |
| | | return (domain.startsWith(Constants.HTTPS) || domain.startsWith(Constants.HTTP)) ? |
| | | domain + StringUtils.SLASH + properties.getBucketName() : header + domain + StringUtils.SLASH + properties.getBucketName(); |
| | | } |
| | | return header + endpoint + StringUtils.SLASH + properties.getBucketName(); |
| | | } |
| | | |
| | | /** |
| | | * çæä¸ä¸ªç¬¦åç¹å®è§åçãå¯ä¸çæä»¶è·¯å¾ãéè¿ä½¿ç¨æ¥æãUUIDãåç¼ååç¼çå
ç´ çç»åï¼ç¡®ä¿äºæä»¶è·¯å¾çç¬ä¸æ äºæ§ |
| | | * |
| | | * @param prefix åç¼ |
| | | * @param suffix åç¼ |
| | | * @return æä»¶è·¯å¾ |
| | | */ |
| | | public String getPath(String prefix, String suffix) { |
| | | // çæuuid |
| | | String uuid = IdUtil.fastSimpleUUID(); |
| | | // çææ¥æè·¯å¾ |
| | | String datePath = DateUtils.datePath(); |
| | | // æ¼æ¥è·¯å¾ |
| | | String path = StringUtils.isNotEmpty(prefix) ? |
| | | prefix + StringUtils.SLASH + datePath + StringUtils.SLASH + uuid : datePath + StringUtils.SLASH + uuid; |
| | | return path + suffix; |
| | | } |
| | | |
| | | /** |
| | | * ç§»é¤è·¯å¾ä¸çåºç¡URLé¨åï¼å¾å°ç¸å¯¹è·¯å¾ |
| | | * |
| | | * @param path 宿´çè·¯å¾ï¼å
æ¬åºç¡URLåç¸å¯¹è·¯å¾ |
| | | * @return å»é¤åºç¡URLåçç¸å¯¹è·¯å¾ |
| | | */ |
| | | public String removeBaseUrl(String path) { |
| | | return path.replace(getUrl() + StringUtils.SLASH, ""); |
| | | } |
| | | |
| | | /** |
| | | * æå¡å |
| | | */ |
| | | public String getConfigKey() { |
| | | return configKey; |
| | | } |
| | | |
| | | /** |
| | | * è·åæ¯å¦ä½¿ç¨ HTTPS çé
ç½®ï¼å¹¶è¿åç¸åºçå议头é¨ã |
| | | * |
| | | * @return å议头é¨ï¼æ ¹æ®æ¯å¦ä½¿ç¨ HTTPS è¿å "https://" æ "http://" |
| | | */ |
| | | public String getIsHttps() { |
| | | return OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? Constants.HTTPS : Constants.HTTP; |
| | | } |
| | | |
| | | /** |
| | |
| | | return AccessPolicyType.getByType(properties.getAccessPolicy()); |
| | | } |
| | | |
| | | /** |
| | | * çæ AWS S3 å卿¡¶è®¿é®çç¥ |
| | | * |
| | | * @param bucketName å卿¡¶ |
| | | * @param policyType æ¡¶çç¥ç±»å |
| | | * @return 符å AWS S3 å卿¡¶è®¿é®çç¥æ ¼å¼çå符串 |
| | | */ |
| | | private static String getPolicy(String bucketName, PolicyType policyType) { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); |
| | | builder.append(switch (policyType) { |
| | | case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n"; |
| | | case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n"; |
| | | default -> "\"s3:GetBucketLocation\"\n"; |
| | | }); |
| | | builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("\"\n},\n"); |
| | | if (policyType == PolicyType.READ) { |
| | | builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("\"\n},\n"); |
| | | } |
| | | builder.append("{\n\"Action\": "); |
| | | builder.append(switch (policyType) { |
| | | case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"; |
| | | case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"; |
| | | default -> "\"s3:GetObject\",\n"; |
| | | }); |
| | | builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); |
| | | builder.append(bucketName); |
| | | builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n"); |
| | | return builder.toString(); |
| | | String policy = switch (policyType) { |
| | | case WRITE -> """ |
| | | { |
| | | "Version": "2012-10-17", |
| | | "Statement": [] |
| | | } |
| | | """; |
| | | case READ_WRITE -> """ |
| | | { |
| | | "Version": "2012-10-17", |
| | | "Statement": [ |
| | | { |
| | | "Effect": "Allow", |
| | | "Principal": "*", |
| | | "Action": [ |
| | | "s3:GetBucketLocation", |
| | | "s3:ListBucket", |
| | | "s3:ListBucketMultipartUploads" |
| | | ], |
| | | "Resource": "arn:aws:s3:::bucketName" |
| | | }, |
| | | { |
| | | "Effect": "Allow", |
| | | "Principal": "*", |
| | | "Action": [ |
| | | "s3:AbortMultipartUpload", |
| | | "s3:DeleteObject", |
| | | "s3:GetObject", |
| | | "s3:ListMultipartUploadParts", |
| | | "s3:PutObject" |
| | | ], |
| | | "Resource": "arn:aws:s3:::bucketName/*" |
| | | } |
| | | ] |
| | | } |
| | | """; |
| | | case READ -> """ |
| | | { |
| | | "Version": "2012-10-17", |
| | | "Statement": [ |
| | | { |
| | | "Effect": "Allow", |
| | | "Principal": "*", |
| | | "Action": ["s3:GetBucketLocation"], |
| | | "Resource": "arn:aws:s3:::bucketName" |
| | | }, |
| | | { |
| | | "Effect": "Deny", |
| | | "Principal": "*", |
| | | "Action": ["s3:ListBucket"], |
| | | "Resource": "arn:aws:s3:::bucketName" |
| | | }, |
| | | { |
| | | "Effect": "Allow", |
| | | "Principal": "*", |
| | | "Action": "s3:GetObject", |
| | | "Resource": "arn:aws:s3:::bucketName/*" |
| | | } |
| | | ] |
| | | } |
| | | """; |
| | | }; |
| | | return policy.replaceAll("bucketName", bucketName); |
| | | } |
| | | |
| | | } |
| | |
| | | * æä»¶å |
| | | */ |
| | | private String filename; |
| | | |
| | | /** |
| | | * å·²ä¸ä¼ 对象çå®ä½æ è®°ï¼ç¨æ¥æ ¡éªæä»¶ï¼ |
| | | */ |
| | | private String eTag; |
| | | |
| | | } |
| | |
| | | package org.dromara.common.oss.enumd; |
| | | |
| | | import com.amazonaws.services.s3.model.CannedAccessControlList; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import software.amazon.awssdk.services.s3.model.BucketCannedACL; |
| | | import software.amazon.awssdk.services.s3.model.ObjectCannedACL; |
| | | |
| | | /** |
| | | * 桶访é®çç¥é
ç½® |
| | |
| | | /** |
| | | * private |
| | | */ |
| | | PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE), |
| | | PRIVATE("0", BucketCannedACL.PRIVATE, ObjectCannedACL.PRIVATE, PolicyType.WRITE), |
| | | |
| | | /** |
| | | * public |
| | | */ |
| | | PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ), |
| | | PUBLIC("1", BucketCannedACL.PUBLIC_READ_WRITE, ObjectCannedACL.PUBLIC_READ_WRITE, PolicyType.READ_WRITE), |
| | | |
| | | /** |
| | | * custom |
| | | */ |
| | | CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ); |
| | | CUSTOM("2", BucketCannedACL.PUBLIC_READ, ObjectCannedACL.PUBLIC_READ, PolicyType.READ); |
| | | |
| | | /** |
| | | * æ¡¶ æéç±»å |
| | | * æ¡¶ æéç±»åï¼æ°æ®åºå¼ï¼ |
| | | */ |
| | | private final String type; |
| | | |
| | | /** |
| | | * æ¡¶ æéç±»å |
| | | */ |
| | | private final BucketCannedACL bucketCannedACL; |
| | | |
| | | /** |
| | | * æä»¶å¯¹è±¡ æéç±»å |
| | | */ |
| | | private final CannedAccessControlList acl; |
| | | private final ObjectCannedACL objectCannedACL; |
| | | |
| | | /** |
| | | * æ¡¶çç¥ç±»å |
| | |
| | | package org.dromara.common.oss.factory; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | |
| | | import org.dromara.common.oss.properties.OssProperties; |
| | | import org.dromara.common.redis.utils.CacheUtils; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ Factory |
| | |
| | | public class OssFactory { |
| | | |
| | | private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>(); |
| | | private static final ReentrantLock LOCK = new ReentrantLock(); |
| | | |
| | | /** |
| | | * è·åé»è®¤å®ä¾ |
| | |
| | | /** |
| | | * æ ¹æ®ç±»åè·åå®ä¾ |
| | | */ |
| | | public static synchronized OssClient instance(String configKey) { |
| | | public static OssClient instance(String configKey) { |
| | | String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey); |
| | | if (json == null) { |
| | | throw new OssException("ç³»ç»å¼å¸¸, '" + configKey + "'é
置信æ¯ä¸åå¨!"); |
| | |
| | | // 使ç¨ç§æ·æ è¯é¿å
å¤ä¸ªç§æ·ç¸åkeyå®ä¾è¦ç |
| | | String key = properties.getTenantId() + ":" + configKey; |
| | | OssClient client = CLIENT_CACHE.get(key); |
| | | if (client == null) { |
| | | CLIENT_CACHE.put(key, new OssClient(configKey, properties)); |
| | | log.info("å建OSSå®ä¾ key => {}", configKey); |
| | | return CLIENT_CACHE.get(key); |
| | | } |
| | | // é
ç½®ä¸ç¸ååéæ°æå»º |
| | | if (!client.checkPropertiesSame(properties)) { |
| | | CLIENT_CACHE.put(key, new OssClient(configKey, properties)); |
| | | log.info("éè½½OSSå®ä¾ key => {}", configKey); |
| | | return CLIENT_CACHE.get(key); |
| | | // 客æ·ç«¯ä¸å卿é
ç½®ä¸ç¸ååéæ°æå»º |
| | | if (client == null || !client.checkPropertiesSame(properties)) { |
| | | LOCK.lock(); |
| | | try { |
| | | client = CLIENT_CACHE.get(key); |
| | | if (client == null || !client.checkPropertiesSame(properties)) { |
| | | CLIENT_CACHE.put(key, new OssClient(configKey, properties)); |
| | | log.info("å建OSSå®ä¾ key => {}", configKey); |
| | | return CLIENT_CACHE.get(key); |
| | | } |
| | | } finally { |
| | | LOCK.unlock(); |
| | | } |
| | | } |
| | | return client; |
| | | } |
| | |
| | | package org.dromara.common.ratelimiter.aspectj; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.MessageUtils; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.ratelimiter.annotation.RateLimiter; |
| | | import org.dromara.common.ratelimiter.enums.LimitType; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.MessageUtils; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.ratelimiter.annotation.RateLimiter; |
| | | import org.dromara.common.ratelimiter.enums.LimitType; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import org.redisson.api.RateType; |
| | | import org.springframework.context.expression.BeanFactoryResolver; |
| | | import org.springframework.context.expression.MethodBasedEvaluationContext; |
| | | import org.springframework.core.DefaultParameterNameDiscoverer; |
| | | import org.springframework.core.ParameterNameDiscoverer; |
| | | import org.springframework.expression.EvaluationContext; |
| | | import org.springframework.expression.Expression; |
| | | import org.springframework.expression.ExpressionParser; |
| | | import org.springframework.expression.ParserContext; |
| | | import org.springframework.expression.common.TemplateParserContext; |
| | | import org.springframework.expression.spel.standard.SpelExpressionParser; |
| | | import org.springframework.expression.spel.support.StandardEvaluationContext; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | |
| | | */ |
| | | private final ParserContext parserContext = new TemplateParserContext(); |
| | | /** |
| | | * å®ä¹spelä¸ä¸æå¯¹è±¡è¿è¡è§£æ |
| | | */ |
| | | private final EvaluationContext context = new StandardEvaluationContext(); |
| | | /** |
| | | * æ¹æ³åæ°è§£æå¨ |
| | | */ |
| | | private final ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); |
| | | |
| | | |
| | | @Before("@annotation(rateLimiter)") |
| | | public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable { |
| | | public void doBefore(JoinPoint point, RateLimiter rateLimiter) { |
| | | int time = rateLimiter.time(); |
| | | int count = rateLimiter.count(); |
| | | String combineKey = getCombineKey(rateLimiter, point); |
| | | try { |
| | | String combineKey = getCombineKey(rateLimiter, point); |
| | | RateType rateType = RateType.OVERALL; |
| | | if (rateLimiter.limitType() == LimitType.CLUSTER) { |
| | | rateType = RateType.PER_CLIENT; |
| | |
| | | if (e instanceof ServiceException) { |
| | | throw e; |
| | | } else { |
| | | throw new RuntimeException("æå¡å¨éæµå¼å¸¸ï¼è¯·ç¨ååè¯"); |
| | | throw new RuntimeException("æå¡å¨éæµå¼å¸¸ï¼è¯·ç¨ååè¯", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { |
| | | private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { |
| | | String key = rateLimiter.key(); |
| | | // è·åæ¹æ³(éè¿æ¹æ³ç¾åæ¥è·å) |
| | | MethodSignature signature = (MethodSignature) point.getSignature(); |
| | | Method method = signature.getMethod(); |
| | | Class<?> targetClass = method.getDeclaringClass(); |
| | | // 夿æ¯å¦æ¯spelæ ¼å¼ |
| | | if (StringUtils.containsAny(key, "#")) { |
| | | // è·ååæ°å¼ |
| | | if (StringUtils.isNotBlank(key)) { |
| | | MethodSignature signature = (MethodSignature) point.getSignature(); |
| | | Method targetMethod = signature.getMethod(); |
| | | Object[] args = point.getArgs(); |
| | | // è·åæ¹æ³ä¸åæ°çåç§° |
| | | String[] parameterNames = pnd.getParameterNames(method); |
| | | if (ArrayUtil.isEmpty(parameterNames)) { |
| | | throw new ServiceException("éæµkeyè§£æå¼å¸¸!请è系管çå!"); |
| | | //noinspection DataFlowIssue |
| | | MethodBasedEvaluationContext context = |
| | | new MethodBasedEvaluationContext(null, targetMethod, args, pnd); |
| | | context.setBeanResolver(new BeanFactoryResolver(SpringUtils.getBeanFactory())); |
| | | Expression expression; |
| | | if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) |
| | | && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { |
| | | expression = parser.parseExpression(key, parserContext); |
| | | } else { |
| | | expression = parser.parseExpression(key); |
| | | } |
| | | for (int i = 0; i < parameterNames.length; i++) { |
| | | context.setVariable(parameterNames[i], args[i]); |
| | | } |
| | | // è§£æè¿åç»key |
| | | try { |
| | | Expression expression; |
| | | if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) |
| | | && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { |
| | | expression = parser.parseExpression(key, parserContext); |
| | | } else { |
| | | expression = parser.parseExpression(key); |
| | | } |
| | | key = expression.getValue(context, String.class) + ":"; |
| | | } catch (Exception e) { |
| | | throw new ServiceException("éæµkeyè§£æå¼å¸¸!请è系管çå!"); |
| | | } |
| | | key = expression.getValue(context, String.class); |
| | | } |
| | | StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY); |
| | | stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":"); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | {
|
| | | "org.dromara.common.ratelimiter.annotation.RateLimiter@key": {
|
| | | "method": {
|
| | | "parameters": true
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.ben-manes.caffeine</groupId> |
| | | <artifactId>caffeine</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.datatype</groupId> |
| | | <artifactId>jackson-datatype-jsr310</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.redis.config; |
| | | |
| | | import com.github.benmanes.caffeine.cache.Cache; |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import org.dromara.common.redis.manager.PlusSpringCacheManager; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * ç¼åé
ç½® |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @AutoConfiguration |
| | | @EnableCaching |
| | | public class CacheConfig { |
| | | |
| | | /** |
| | | * caffeine æ¬å°ç¼åå¤çå¨ |
| | | */ |
| | | @Bean |
| | | public Cache<Object, Object> caffeine() { |
| | | return Caffeine.newBuilder() |
| | | // 设置æå䏿¬¡åå
¥æè®¿é®åç»è¿åºå®æ¶é´è¿æ |
| | | .expireAfterWrite(30, TimeUnit.SECONDS) |
| | | // åå§çç¼å空é´å¤§å° |
| | | .initialCapacity(100) |
| | | // ç¼åçæå¤§æ¡æ° |
| | | .maximumSize(1000) |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹ç¼å管çå¨ æ´åspring-cache |
| | | */ |
| | | @Bean |
| | | public CacheManager cacheManager() { |
| | | return new PlusSpringCacheManager(); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.fasterxml.jackson.annotation.PropertyAccessor; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.redis.config.properties.RedissonProperties; |
| | | import org.dromara.common.redis.handler.KeyPrefixHandler; |
| | | import org.dromara.common.redis.manager.PlusSpringCacheManager; |
| | | import org.dromara.common.redis.handler.RedisExceptionHandler; |
| | | import org.redisson.client.codec.StringCodec; |
| | | import org.redisson.codec.CompositeCodec; |
| | | import org.redisson.codec.TypedJsonJacksonCodec; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.core.task.VirtualThreadTaskExecutor; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.TimeZone; |
| | | |
| | | /** |
| | | * redisé
ç½® |
| | |
| | | */ |
| | | @Slf4j |
| | | @AutoConfiguration |
| | | @EnableCaching |
| | | @EnableConfigurationProperties(RedissonProperties.class) |
| | | public class RedisConfig { |
| | | |
| | | @Autowired |
| | | private RedissonProperties redissonProperties; |
| | | |
| | | @Autowired |
| | | private ObjectMapper objectMapper; |
| | | |
| | | @Bean |
| | | public RedissonAutoConfigurationCustomizer redissonCustomizer() { |
| | | return config -> { |
| | | ObjectMapper om = objectMapper.copy(); |
| | | JavaTimeModule javaTimeModule = new JavaTimeModule(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); |
| | | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); |
| | | ObjectMapper om = new ObjectMapper(); |
| | | om.registerModule(javaTimeModule); |
| | | om.setTimeZone(TimeZone.getDefault()); |
| | | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
| | | // æå®åºååè¾å
¥çç±»åï¼ç±»å¿
é¡»æ¯éfinal修饰çãåºååæ¶å°å¯¹è±¡å
¨ç±»åä¸èµ·ä¿å䏿¥ |
| | | om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); |
| | |
| | | // ç¼å Lua èæ¬ åå°ç½ç»ä¼ è¾(redisson 大é¨åçåè½é½æ¯åºäº Lua èæ¬å®ç°) |
| | | .setUseScriptCache(true) |
| | | .setCodec(codec); |
| | | if (SpringUtils.isVirtual()) { |
| | | config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-")); |
| | | } |
| | | RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); |
| | | if (ObjectUtil.isNotNull(singleServerConfig)) { |
| | | // 使ç¨åæºæ¨¡å¼ |
| | |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹ç¼å管çå¨ æ´åspring-cache |
| | | * å¼å¸¸å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public CacheManager cacheManager() { |
| | | return new PlusSpringCacheManager(); |
| | | public RedisExceptionHandler redisExceptionHandler() { |
| | | return new RedisExceptionHandler(); |
| | | } |
| | | |
| | | /** |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.redis.handler; |
| | | |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.baomidou.lock.exception.LockFailureException; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | /** |
| | | * Rediså¼å¸¸å¤çå¨ |
| | | * |
| | | * @author AprilWind |
| | | */ |
| | | @Slf4j |
| | | @RestControllerAdvice |
| | | public class RedisExceptionHandler { |
| | | |
| | | /** |
| | | * åå¸å¼éLock4jå¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(LockFailureException.class) |
| | | public R<Void> handleLockFailureException(LockFailureException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("è·åé失败äº'{}',åçLock4jå¼å¸¸." + requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_UNAVAILABLE, "ä¸å¡å¤çä¸ï¼è¯·ç¨ååè¯..."); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.redis.manager; |
| | | |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.springframework.cache.Cache; |
| | | |
| | | import java.util.concurrent.Callable; |
| | | |
| | | /** |
| | | * Cache è£
饰卿¨¡å¼(ç¨äºæ©å± Caffeine ä¸çº§ç¼å) |
| | | * |
| | | * @author LionLi |
| | | */ |
| | | public class CaffeineCacheDecorator implements Cache { |
| | | |
| | | private static final com.github.benmanes.caffeine.cache.Cache<Object, Object> |
| | | CAFFEINE = SpringUtils.getBean("caffeine"); |
| | | |
| | | private final Cache cache; |
| | | |
| | | public CaffeineCacheDecorator(Cache cache) { |
| | | this.cache = cache; |
| | | } |
| | | |
| | | @Override |
| | | public String getName() { |
| | | return cache.getName(); |
| | | } |
| | | |
| | | @Override |
| | | public Object getNativeCache() { |
| | | return cache.getNativeCache(); |
| | | } |
| | | |
| | | public String getUniqueKey(Object key) { |
| | | return cache.getName() + ":" + key; |
| | | } |
| | | |
| | | @Override |
| | | public ValueWrapper get(Object key) { |
| | | Object o = CAFFEINE.get(getUniqueKey(key), k -> cache.get(key)); |
| | | return (ValueWrapper) o; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | public <T> T get(Object key, Class<T> type) { |
| | | Object o = CAFFEINE.get(getUniqueKey(key), k -> cache.get(key, type)); |
| | | return (T) o; |
| | | } |
| | | |
| | | @Override |
| | | public void put(Object key, Object value) { |
| | | CAFFEINE.invalidate(getUniqueKey(key)); |
| | | cache.put(key, value); |
| | | } |
| | | |
| | | public ValueWrapper putIfAbsent(Object key, Object value) { |
| | | CAFFEINE.invalidate(getUniqueKey(key)); |
| | | return cache.putIfAbsent(key, value); |
| | | } |
| | | |
| | | @Override |
| | | public void evict(Object key) { |
| | | evictIfPresent(key); |
| | | } |
| | | |
| | | public boolean evictIfPresent(Object key) { |
| | | boolean b = cache.evictIfPresent(key); |
| | | if (b) { |
| | | CAFFEINE.invalidate(getUniqueKey(key)); |
| | | } |
| | | return b; |
| | | } |
| | | |
| | | @Override |
| | | public void clear() { |
| | | cache.clear(); |
| | | } |
| | | |
| | | public boolean invalidate() { |
| | | return cache.invalidate(); |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public <T> T get(Object key, Callable<T> valueLoader) { |
| | | Object o = CAFFEINE.get(getUniqueKey(key), k -> cache.get(key, valueLoader)); |
| | | return (T) o; |
| | | } |
| | | |
| | | } |
| | |
| | | private Cache createMap(String name, CacheConfig config) { |
| | | RMap<Object, Object> map = RedisUtils.getClient().getMap(name); |
| | | |
| | | Cache cache = new RedissonCache(map, allowNullValues); |
| | | Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, allowNullValues)); |
| | | if (transactionAware) { |
| | | cache = new TransactionAwareCacheDecorator(cache); |
| | | } |
| | |
| | | private Cache createMapCache(String name, CacheConfig config) { |
| | | RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name); |
| | | |
| | | Cache cache = new RedissonCache(map, config, allowNullValues); |
| | | Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, config, allowNullValues)); |
| | | if (transactionAware) { |
| | | cache = new TransactionAwareCacheDecorator(cache); |
| | | } |
| | |
| | | consumer.accept(msg); |
| | | } |
| | | |
| | | /** |
| | | * å叿¶æ¯å°æå®çé¢é |
| | | * |
| | | * @param channelKey éékey |
| | | * @param msg åéæ°æ® |
| | | */ |
| | | public static <T> void publish(String channelKey, T msg) { |
| | | RTopic topic = CLIENT.getTopic(channelKey); |
| | | topic.publish(msg); |
| | |
| | | bucket.setAndKeepTTL(value); |
| | | } catch (Exception e) { |
| | | long timeToLive = bucket.remainTimeToLive(); |
| | | setCacheObject(key, value, Duration.ofMillis(timeToLive)); |
| | | if (timeToLive == -1) { |
| | | setCacheObject(key, value); |
| | | } else { |
| | | setCacheObject(key, value, Duration.ofMillis(timeToLive)); |
| | | } |
| | | } |
| | | } else { |
| | | bucket.set(value); |
| | |
| | | org.dromara.common.redis.config.RedisConfig |
| | | org.dromara.common.redis.config.CacheConfig |
| | |
| | | <artifactId>sa-token-jwt</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.ben-manes.caffeine</groupId> |
| | | <artifactId>caffeine</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | import org.dromara.common.core.factory.YmlPropertySourceFactory; |
| | | import org.dromara.common.satoken.core.dao.PlusSaTokenDao; |
| | | import org.dromara.common.satoken.core.service.SaPermissionImpl; |
| | | import org.dromara.common.satoken.handler.SaTokenExceptionHandler; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.PropertySource; |
| | |
| | | return new PlusSaTokenDao(); |
| | | } |
| | | |
| | | /** |
| | | * å¼å¸¸å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public SaTokenExceptionHandler saTokenExceptionHandler() { |
| | | return new SaTokenExceptionHandler(); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import cn.dev33.satoken.dao.SaTokenDao; |
| | | import cn.dev33.satoken.util.SaFoxUtil; |
| | | import cn.hutool.core.lang.Console; |
| | | import com.github.benmanes.caffeine.cache.Cache; |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * Sa-Tokenæä¹
屿¥å£(ä½¿ç¨æ¡æ¶èªå¸¦RedisUtilså®ç° åè®®ç»ä¸) |
| | | * <p> |
| | | * éç¨ caffeine + redis å¤çº§ç¼å ä¼åå¹¶åæ¥è¯¢æç |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class PlusSaTokenDao implements SaTokenDao { |
| | | |
| | | private static final Cache<String, Object> CAFFEINE = Caffeine.newBuilder() |
| | | // 设置æå䏿¬¡åå
¥æè®¿é®åç»è¿åºå®æ¶é´è¿æ |
| | | .expireAfterWrite(5, TimeUnit.SECONDS) |
| | | // åå§çç¼å空é´å¤§å° |
| | | .initialCapacity(100) |
| | | // ç¼åçæå¤§æ¡æ° |
| | | .maximumSize(1000) |
| | | .build(); |
| | | |
| | | /** |
| | | * è·åValueï¼å¦æ è¿ç©º |
| | | */ |
| | | @Override |
| | | public String get(String key) { |
| | | return RedisUtils.getCacheObject(key); |
| | | Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); |
| | | return (String) o; |
| | | } |
| | | |
| | | /** |
| | |
| | | } else { |
| | | RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout)); |
| | | } |
| | | CAFFEINE.put(key, value); |
| | | } |
| | | |
| | | /** |
| | |
| | | public void update(String key, String value) { |
| | | if (RedisUtils.hasKey(key)) { |
| | | RedisUtils.setCacheObject(key, value, true); |
| | | CAFFEINE.put(key, value); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public Object getObject(String key) { |
| | | return RedisUtils.getCacheObject(key); |
| | | Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); |
| | | return o; |
| | | } |
| | | |
| | | /** |
| | |
| | | } else { |
| | | RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout)); |
| | | } |
| | | CAFFEINE.put(key, object); |
| | | } |
| | | |
| | | /** |
| | |
| | | public void updateObject(String key, Object object) { |
| | | if (RedisUtils.hasKey(key)) { |
| | | RedisUtils.setCacheObject(key, object, true); |
| | | CAFFEINE.put(key, object); |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * æç´¢æ°æ® |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) { |
| | | Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*"); |
| | | List<String> list = new ArrayList<>(keys); |
| | | return SaFoxUtil.searchList(list, start, size, sortType); |
| | | String keyStr = prefix + "*" + keyword + "*"; |
| | | return (List<String>) CAFFEINE.get(keyStr, k -> { |
| | | Collection<String> keys = RedisUtils.keys(keyStr); |
| | | List<String> list = new ArrayList<>(keys); |
| | | return SaFoxUtil.searchList(list, start, size, sortType); |
| | | }); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.satoken.handler; |
| | | |
| | | import cn.dev33.satoken.exception.NotLoginException; |
| | | import cn.dev33.satoken.exception.NotPermissionException; |
| | | import cn.dev33.satoken.exception.NotRoleException; |
| | | import cn.hutool.http.HttpStatus; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | /** |
| | | * SaTokenå¼å¸¸å¤çå¨ |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @RestControllerAdvice |
| | | public class SaTokenExceptionHandler { |
| | | |
| | | /** |
| | | * æéç å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotPermissionException.class) |
| | | public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',æéç æ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * è§è²æéå¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotRoleException.class) |
| | | public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',è§è²æéæ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * 认è¯å¤±è´¥ |
| | | */ |
| | | @ExceptionHandler(NotLoginException.class) |
| | | public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',认è¯å¤±è´¥'{}',æ æ³è®¿é®ç³»ç»èµæº", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº"); |
| | | } |
| | | |
| | | } |
| | |
| | | package org.dromara.common.satoken.utils; |
| | | |
| | | import cn.dev33.satoken.context.SaHolder; |
| | | import cn.dev33.satoken.context.model.SaStorage; |
| | | import cn.dev33.satoken.session.SaSession; |
| | | import cn.dev33.satoken.stp.SaLoginModel; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | |
| | | import org.dromara.common.core.enums.UserType; |
| | | |
| | | import java.util.Set; |
| | | import java.util.function.Supplier; |
| | | |
| | | /** |
| | | * ç»å½é´æå©æ |
| | |
| | | public static final String LOGIN_USER_KEY = "loginUser"; |
| | | public static final String TENANT_KEY = "tenantId"; |
| | | public static final String USER_KEY = "userId"; |
| | | public static final String USER_NAME_KEY = "userName"; |
| | | public static final String DEPT_KEY = "deptId"; |
| | | public static final String DEPT_NAME_KEY = "deptName"; |
| | | public static final String DEPT_CATEGORY_KEY = "deptCategory"; |
| | | public static final String CLIENT_KEY = "clientid"; |
| | | public static final String TENANT_ADMIN_KEY = "isTenantAdmin"; |
| | | |
| | | /** |
| | | * ç»å½ç³»ç» åºäº 设å¤ç±»å |
| | |
| | | * @param model é
ç½®åæ° |
| | | */ |
| | | public static void login(LoginUser loginUser, SaLoginModel model) { |
| | | SaStorage storage = SaHolder.getStorage(); |
| | | storage.set(LOGIN_USER_KEY, loginUser); |
| | | storage.set(TENANT_KEY, loginUser.getTenantId()); |
| | | storage.set(USER_KEY, loginUser.getUserId()); |
| | | storage.set(DEPT_KEY, loginUser.getDeptId()); |
| | | model = ObjectUtil.defaultIfNull(model, new SaLoginModel()); |
| | | StpUtil.login(loginUser.getLoginId(), |
| | | model.setExtra(TENANT_KEY, loginUser.getTenantId()) |
| | | .setExtra(USER_KEY, loginUser.getUserId()) |
| | | .setExtra(DEPT_KEY, loginUser.getDeptId())); |
| | | SaSession tokenSession = StpUtil.getTokenSession(); |
| | | tokenSession.updateTimeout(model.getTimeout()); |
| | | tokenSession.set(LOGIN_USER_KEY, loginUser); |
| | | .setExtra(USER_NAME_KEY, loginUser.getUsername()) |
| | | .setExtra(DEPT_KEY, loginUser.getDeptId()) |
| | | .setExtra(DEPT_NAME_KEY, loginUser.getDeptName()) |
| | | .setExtra(DEPT_CATEGORY_KEY, loginUser.getDeptCategory()) |
| | | ); |
| | | StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·(å¤çº§ç¼å) |
| | | */ |
| | | public static LoginUser getLoginUser() { |
| | | return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> { |
| | | SaSession session = StpUtil.getTokenSession(); |
| | | if (ObjectUtil.isNull(session)) { |
| | | return null; |
| | | } |
| | | return session.get(LOGIN_USER_KEY); |
| | | }); |
| | | SaSession session = StpUtil.getTokenSession(); |
| | | if (ObjectUtil.isNull(session)) { |
| | | return null; |
| | | } |
| | | return (LoginUser) session.get(LOGIN_USER_KEY); |
| | | } |
| | | |
| | | /** |
| | |
| | | * è·åç¨æ·id |
| | | */ |
| | | public static Long getUserId() { |
| | | return Convert.toLong(getExtra(USER_KEY)); |
| | | return Convert.toLong(getExtra(USER_KEY)); |
| | | } |
| | | |
| | | /** |
| | |
| | | return Convert.toLong(getExtra(DEPT_KEY)); |
| | | } |
| | | |
| | | /** |
| | | * è·åé¨é¨å |
| | | */ |
| | | public static String getDeptName() { |
| | | return Convert.toStr(getExtra(DEPT_NAME_KEY)); |
| | | } |
| | | |
| | | /** |
| | | * è·åé¨é¨ç±»å«ç¼ç |
| | | */ |
| | | public static String getDeptCategory() { |
| | | return Convert.toStr(getExtra(DEPT_CATEGORY_KEY)); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½å Token çæ©å±ä¿¡æ¯ |
| | | * |
| | | * @param key é®å¼ |
| | | * @return 对åºçæ©å±æ°æ® |
| | | */ |
| | | private static Object getExtra(String key) { |
| | | return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key)); |
| | | try { |
| | | return StpUtil.getExtra(key); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | return UserConstants.SUPER_ADMIN_ID.equals(userId); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºè¶
级管çå |
| | | * |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean isSuperAdmin() { |
| | | return isSuperAdmin(getUserId()); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºè¶
级管çå |
| | | * æ¯å¦ä¸ºç§æ·ç®¡çå |
| | | * |
| | | * @param rolePermission è§è²æéæ è¯ç» |
| | | * @return ç»æ |
| | |
| | | return rolePermission.contains(TenantConstants.TENANT_ADMIN_ROLE_KEY); |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç§æ·ç®¡çå |
| | | * |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean isTenantAdmin() { |
| | | Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> { |
| | | return isTenantAdmin(getLoginUser().getRolePermission()); |
| | | }); |
| | | return Convert.toBool(value); |
| | | return Convert.toBool(isTenantAdmin(getLoginUser().getRolePermission())); |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥å½åç¨æ·æ¯å¦å·²ç»å½ |
| | | * |
| | | * @return ç»æ |
| | | */ |
| | | public static boolean isLogin() { |
| | | return getLoginUser() != null; |
| | | } |
| | | |
| | | public static Object getStorageIfAbsentSet(String key, Supplier<Object> handle) { |
| | | try { |
| | | Object obj = SaHolder.getStorage().get(key); |
| | | if (ObjectUtil.isNull(obj)) { |
| | | obj = handle.get(); |
| | | SaHolder.getStorage().set(key, obj); |
| | | } |
| | | return obj; |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | |
| | | import cn.dev33.satoken.interceptor.SaInterceptor; |
| | | import cn.dev33.satoken.router.SaRouter; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.security.config.properties.SecurityProperties; |
| | | import org.dromara.common.security.handler.AllUrlHandler; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | // 注åè·¯ç±æ¦æªå¨ï¼èªå®ä¹éªè¯è§å |
| | | registry.addInterceptor(new SaInterceptor(handler -> { |
| | | AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class); |
| | | // ç»å½éªè¯ -- æé¤å¤ä¸ªè·¯å¾ |
| | | SaRouter |
| | | // è·åææç |
| | | .match(allUrlHandler.getUrls()) |
| | | // å¯¹æªæé¤çè·¯å¾è¿è¡æ£æ¥ |
| | | .check(() -> { |
| | | // æ£æ¥æ¯å¦ç»å½ æ¯å¦ætoken |
| | | StpUtil.checkLogin(); |
| | | AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class); |
| | | // ç»å½éªè¯ -- æé¤å¤ä¸ªè·¯å¾ |
| | | SaRouter |
| | | // è·åææç |
| | | .match(allUrlHandler.getUrls()) |
| | | // å¯¹æªæé¤çè·¯å¾è¿è¡æ£æ¥ |
| | | .check(() -> { |
| | | // æ£æ¥æ¯å¦ç»å½ æ¯å¦ætoken |
| | | StpUtil.checkLogin(); |
| | | |
| | | // æ£æ¥ header ä¸ param éç clientid ä¸ token éçæ¯å¦ä¸è´ |
| | | String headerCid = ServletUtils.getRequest().getHeader(LoginHelper.CLIENT_KEY); |
| | | String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY); |
| | | String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString(); |
| | | if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) { |
| | | // token æ æ |
| | | throw NotLoginException.newInstance(StpUtil.getLoginType(), |
| | | "-100", "客æ·ç«¯IDä¸Tokenä¸å¹é
", |
| | | StpUtil.getTokenValue()); |
| | | } |
| | | // æ£æ¥ header ä¸ param éç clientid ä¸ token éçæ¯å¦ä¸è´ |
| | | String headerCid = ServletUtils.getRequest().getHeader(LoginHelper.CLIENT_KEY); |
| | | String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY); |
| | | String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString(); |
| | | if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) { |
| | | // token æ æ |
| | | throw NotLoginException.newInstance(StpUtil.getLoginType(), |
| | | "-100", "客æ·ç«¯IDä¸Tokenä¸å¹é
", |
| | | StpUtil.getTokenValue()); |
| | | } |
| | | |
| | | // ææçå½±å ç¨äºä¸´æ¶æµè¯ |
| | | // if (log.isDebugEnabled()) { |
| | | // log.info("å©ä½æææ¶é´: {}", StpUtil.getTokenTimeout()); |
| | | // log.info("ä¸´æ¶æææ¶é´: {}", StpUtil.getTokenActivityTimeout()); |
| | | // } |
| | | // ææçå½±å ç¨äºä¸´æ¶æµè¯ |
| | | // if (log.isDebugEnabled()) { |
| | | // log.info("å©ä½æææ¶é´: {}", StpUtil.getTokenTimeout()); |
| | | // log.info("ä¸´æ¶æææ¶é´: {}", StpUtil.getTokenActivityTimeout()); |
| | | // } |
| | | |
| | | }); |
| | | })).addPathPatterns("/**") |
| | | }); |
| | | })).addPathPatterns("/**") |
| | | // æé¤ä¸éè¦æ¦æªçè·¯å¾ |
| | | .excludePathPatterns(securityProperties.getExcludes()); |
| | | } |
| | |
| | | org.dromara.common.security.handler.GlobalExceptionHandler |
| | | org.dromara.common.security.handler.AllUrlHandler |
| | | org.dromara.common.security.config.SecurityConfig |
| | |
| | | <dependency> |
| | | <groupId>org.dromara.sms4j</groupId> |
| | | <artifactId>sms4j-spring-boot-starter</artifactId> |
| | | <exclusions> |
| | | <!-- æé¤äº¬ä¸çä¿¡å
åå¨çfastjsonçå¾
ä½è
åç»ä¿®å¤ --> |
| | | <exclusion> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <!-- RuoYi Common Redis--> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | |
| | | package org.dromara.common.sms.config; |
| | | |
| | | import org.dromara.common.sms.core.dao.PlusSmsDao; |
| | | import org.dromara.sms4j.api.dao.SmsDao; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Primary; |
| | | |
| | | /** |
| | | * çä¿¡é
置类(ææ¶æ²¡ç¨ é¢çæ©å±) |
| | | * çä¿¡é
置类 |
| | | * |
| | | * @author Lion Li |
| | | * @version 4.2.0 |
| | | * @author Feng |
| | | */ |
| | | @AutoConfiguration |
| | | @AutoConfiguration(after = {RedisAutoConfiguration.class}) |
| | | public class SmsAutoConfiguration { |
| | | |
| | | @Primary |
| | | @Bean |
| | | public SmsDao smsDao() { |
| | | return new PlusSmsDao(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.sms.core.dao; |
| | | |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import org.dromara.sms4j.api.dao.SmsDao; |
| | | |
| | | import java.time.Duration; |
| | | |
| | | /** |
| | | * SmsDaoç¼åé
ç½® (ä½¿ç¨æ¡æ¶èªå¸¦RedisUtilså®ç° åè®®ç»ä¸) |
| | | * <p>主è¦ç¨äºçä¿¡éè¯åæ¦æªçç¼å |
| | | * |
| | | * @author Feng |
| | | */ |
| | | public class PlusSmsDao implements SmsDao { |
| | | |
| | | /** |
| | | * åå¨ |
| | | * |
| | | * @param key é® |
| | | * @param value å¼ |
| | | * @param cacheTime ç¼åæ¶é´ï¼åä½ï¼ç§) |
| | | */ |
| | | @Override |
| | | public void set(String key, Object value, long cacheTime) { |
| | | RedisUtils.setCacheObject(GlobalConstants.GLOBAL_REDIS_KEY + key, value, Duration.ofSeconds(cacheTime)); |
| | | } |
| | | |
| | | /** |
| | | * åå¨ |
| | | * |
| | | * @param key é® |
| | | * @param value å¼ |
| | | */ |
| | | @Override |
| | | public void set(String key, Object value) { |
| | | RedisUtils.setCacheObject(GlobalConstants.GLOBAL_REDIS_KEY + key, value, true); |
| | | } |
| | | |
| | | /** |
| | | * 读å |
| | | * |
| | | * @param key é® |
| | | * @return å¼ |
| | | */ |
| | | @Override |
| | | public Object get(String key) { |
| | | return RedisUtils.getCacheObject(GlobalConstants.GLOBAL_REDIS_KEY + key); |
| | | } |
| | | |
| | | /** |
| | | * remove |
| | | * <p> æ ¹æ®keyç§»é¤ç¼å |
| | | * |
| | | * @param key ç¼åé® |
| | | * @return 被å é¤çvalue |
| | | * @author :Wind |
| | | */ |
| | | @Override |
| | | public Object remove(String key) { |
| | | return RedisUtils.deleteObject(GlobalConstants.GLOBAL_REDIS_KEY + key); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
空 |
| | | */ |
| | | @Override |
| | | public void clean() { |
| | | RedisUtils.deleteObject(GlobalConstants.GLOBAL_REDIS_KEY + "sms:"); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 社交ç»å½é
ç½® |
| | | * |
| | |
| | | */ |
| | | private String serverUrl; |
| | | |
| | | /** |
| | | * 请æ±èå´ |
| | | */ |
| | | private List<String> scopes; |
| | | |
| | | } |
| | |
| | | public class SocialProperties { |
| | | |
| | | /** |
| | | * æ¯å¦å¯ç¨ |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * ææç±»å |
| | | */ |
| | | private Map<String, SocialLoginConfigProperties> type; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.social.topiam; |
| | | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.xkcoding.http.support.HttpHeader; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.zhyd.oauth.cache.AuthStateCache; |
| | | import me.zhyd.oauth.config.AuthConfig; |
| | | import me.zhyd.oauth.exception.AuthException; |
| | | import me.zhyd.oauth.model.AuthCallback; |
| | | import me.zhyd.oauth.model.AuthToken; |
| | | import me.zhyd.oauth.model.AuthUser; |
| | | import me.zhyd.oauth.request.AuthDefaultRequest; |
| | | import me.zhyd.oauth.utils.HttpUtils; |
| | | import me.zhyd.oauth.utils.UrlBuilder; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | |
| | | import static org.dromara.common.social.topiam.AuthTopiamSource.TOPIAM; |
| | | |
| | | /** |
| | | * TopIAM 认è¯è¯·æ± |
| | | * |
| | | * @author xlsea |
| | | * @since 2024-01-06 |
| | | */ |
| | | @Slf4j |
| | | public class AuthTopIamRequest extends AuthDefaultRequest { |
| | | |
| | | public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.topiam.server-url"); |
| | | |
| | | /** |
| | | * 设å®å½å±å |
| | | */ |
| | | public AuthTopIamRequest(AuthConfig config) { |
| | | super(config, TOPIAM); |
| | | } |
| | | |
| | | public AuthTopIamRequest(AuthConfig config, AuthStateCache authStateCache) { |
| | | super(config, TOPIAM, authStateCache); |
| | | } |
| | | |
| | | @Override |
| | | protected AuthToken getAccessToken(AuthCallback authCallback) { |
| | | String body = doPostAuthorizationCode(authCallback.getCode()); |
| | | Dict object = JsonUtils.parseMap(body); |
| | | checkResponse(object); |
| | | return AuthToken.builder() |
| | | .accessToken(object.getStr("access_token")) |
| | | .refreshToken(object.getStr("refresh_token")) |
| | | .idToken(object.getStr("id_token")) |
| | | .tokenType(object.getStr("token_type")) |
| | | .scope(object.getStr("scope")) |
| | | .build(); |
| | | } |
| | | |
| | | @Override |
| | | protected AuthUser getUserInfo(AuthToken authToken) { |
| | | String body = doGetUserInfo(authToken); |
| | | Dict object = JsonUtils.parseMap(body); |
| | | checkResponse(object); |
| | | return AuthUser.builder() |
| | | .uuid(object.getStr("sub")) |
| | | .username(object.getStr("preferred_username")) |
| | | .nickname(object.getStr("nickname")) |
| | | .avatar(object.getStr("picture")) |
| | | .email(object.getStr("email")) |
| | | .token(authToken) |
| | | .source(source.toString()) |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | protected String doGetUserInfo(AuthToken authToken) { |
| | | return new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader() |
| | | .add("Content-Type", "application/json") |
| | | .add("Authorization", "Bearer " + authToken.getAccessToken()), false).getBody(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public String authorize(String state) { |
| | | return UrlBuilder.fromBaseUrl(super.authorize(state)) |
| | | .queryParam("scope", StrUtil.join("%20", config.getScopes())) |
| | | .build(); |
| | | } |
| | | |
| | | public static void checkResponse(Dict object) { |
| | | // oauth/token éªè¯å¼å¸¸ |
| | | if (object.containsKey("error")) { |
| | | throw new AuthException(object.getStr("error_description")); |
| | | } |
| | | // user éªè¯å¼å¸¸ |
| | | if (object.containsKey("message")) { |
| | | throw new AuthException(object.getStr("message")); |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.common.social.topiam; |
| | | |
| | | import me.zhyd.oauth.config.AuthSource; |
| | | import me.zhyd.oauth.request.AuthDefaultRequest; |
| | | |
| | | /** |
| | | * Oauth2 é»è®¤æ¥å£è¯´æ |
| | | * |
| | | * @author xlsea |
| | | * @since 2024-01-06 |
| | | */ |
| | | public enum AuthTopiamSource implements AuthSource { |
| | | |
| | | /** |
| | | * æµè¯ |
| | | */ |
| | | TOPIAM { |
| | | /** |
| | | * ææçapi |
| | | */ |
| | | @Override |
| | | public String authorize() { |
| | | return AuthTopIamRequest.SERVER_URL + "/oauth2/auth"; |
| | | } |
| | | |
| | | /** |
| | | * è·åaccessTokençapi |
| | | */ |
| | | @Override |
| | | public String accessToken() { |
| | | return AuthTopIamRequest.SERVER_URL + "/oauth2/token"; |
| | | } |
| | | |
| | | /** |
| | | * è·åç¨æ·ä¿¡æ¯çapi |
| | | */ |
| | | @Override |
| | | public String userInfo() { |
| | | return AuthTopIamRequest.SERVER_URL + "/oauth2/userinfo"; |
| | | } |
| | | |
| | | /** |
| | | * å¹³å°å¯¹åºç AuthRequest å®ç°ç±»ï¼å¿
须继æ¿èª {@link AuthDefaultRequest} |
| | | */ |
| | | @Override |
| | | public Class<? extends AuthDefaultRequest> getTargetClass() { |
| | | return AuthTopIamRequest.class; |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | import org.dromara.common.social.config.properties.SocialLoginConfigProperties; |
| | | import org.dromara.common.social.config.properties.SocialProperties; |
| | | import org.dromara.common.social.maxkey.AuthMaxKeyRequest; |
| | | import org.dromara.common.social.topiam.AuthTopIamRequest; |
| | | |
| | | /** |
| | | * è®¤è¯ææå·¥å
·ç±» |
| | |
| | | AuthConfig.AuthConfigBuilder builder = AuthConfig.builder() |
| | | .clientId(obj.getClientId()) |
| | | .clientSecret(obj.getClientSecret()) |
| | | .redirectUri(obj.getRedirectUri()); |
| | | .redirectUri(obj.getRedirectUri()) |
| | | .scopes(obj.getScopes()); |
| | | return switch (source.toLowerCase()) { |
| | | case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE); |
| | | case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE); |
| | |
| | | case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE); |
| | | case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE); |
| | | case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE); |
| | | case "topiam" -> new AuthTopIamRequest(builder.build(), STATE_CACHE); |
| | | default -> throw new AuthException("æªè·åå°ææçAuthé
ç½®"); |
| | | }; |
| | | } |
| | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | |
| | | |
| | | import cn.dev33.satoken.dao.SaTokenDao; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; |
| | | import org.dromara.common.core.utils.reflect.ReflectUtils; |
| | | import org.dromara.common.mybatis.config.MybatisPlusConfig; |
| | |
| | | import org.redisson.config.SingleServerConfig; |
| | | import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Primary; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç§æ·é
置类 |
| | |
| | | * @author Lion Li |
| | | */ |
| | | @EnableConfigurationProperties(TenantProperties.class) |
| | | @AutoConfiguration(after = {RedisConfig.class, MybatisPlusConfig.class}) |
| | | @AutoConfiguration(after = {RedisConfig.class}) |
| | | @ConditionalOnProperty(value = "tenant.enable", havingValue = "true") |
| | | public class TenantConfig { |
| | | |
| | | /** |
| | | * åå§åç§æ·é
ç½® |
| | | */ |
| | | @Bean |
| | | public boolean tenantInit(MybatisPlusInterceptor mybatisPlusInterceptor, |
| | | TenantProperties tenantProperties) { |
| | | List<InnerInterceptor> interceptors = new ArrayList<>(); |
| | | // å¤ç§æ·æä»¶ å¿
é¡»æ¾å°ç¬¬ä¸ä½ |
| | | interceptors.add(tenantLineInnerInterceptor(tenantProperties)); |
| | | interceptors.addAll(mybatisPlusInterceptor.getInterceptors()); |
| | | mybatisPlusInterceptor.setInterceptors(interceptors); |
| | | return true; |
| | | } |
| | | @ConditionalOnBean(MybatisPlusConfig.class) |
| | | @AutoConfiguration(after = {MybatisPlusConfig.class}) |
| | | static class MybatisPlusConfigation { |
| | | |
| | | /** |
| | | * å¤ç§æ·æä»¶ |
| | | */ |
| | | public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) { |
| | | return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties)); |
| | | /** |
| | | * å¤ç§æ·æä»¶ |
| | | */ |
| | | @Bean |
| | | public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) { |
| | | return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties)); |
| | | } |
| | | |
| | | } |
| | | |
| | | @Bean |
| | |
| | | package org.dromara.common.tenant.handle; |
| | | |
| | | import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | |
| | | if (StringUtils.isBlank(name)) { |
| | | return null; |
| | | } |
| | | if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) { |
| | | return super.map(name); |
| | | } |
| | | if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) { |
| | | return super.map(name); |
| | | } |
| | |
| | | if (StringUtils.isBlank(unmap)) { |
| | | return null; |
| | | } |
| | | if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) { |
| | | return super.unmap(name); |
| | | } |
| | | if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) { |
| | | return super.unmap(name); |
| | | } |
| | |
| | | @Override |
| | | public String translation(Object key, String other) { |
| | | if (key instanceof Long id) { |
| | | return userService.selectNicknameById(id); |
| | | return userService.selectNicknameByIds(id.toString()); |
| | | } else if (key instanceof String ids) { |
| | | return userService.selectNicknameByIds(ids); |
| | | } |
| | | return null; |
| | | } |
| | |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-crypto</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | |
| | | private static final int WIDTH = 160; |
| | | private static final int HEIGHT = 60; |
| | | private static final Color BACKGROUND = Color.PINK; |
| | | private static final Color BACKGROUND = Color.LIGHT_GRAY; |
| | | private static final Font FONT = new Font("Arial", Font.BOLD, 48); |
| | | |
| | | /** |
| | |
| | | package org.dromara.common.web.config; |
| | | |
| | | import org.dromara.common.web.handler.GlobalExceptionHandler; |
| | | import org.dromara.common.web.interceptor.PlusWebInvokeTimeInterceptor; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | |
| | | // è¿åæ°çCorsFilter |
| | | return new CorsFilter(source); |
| | | } |
| | | |
| | | /** |
| | | * å
¨å±å¼å¸¸å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public GlobalExceptionHandler globalExceptionHandler() { |
| | | return new GlobalExceptionHandler(); |
| | | } |
| | | } |
| | |
| | | |
| | | import io.undertow.server.DefaultByteBufferPool; |
| | | import io.undertow.websockets.jsr.WebSocketDeploymentInfo; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; |
| | | import org.springframework.boot.web.server.WebServerFactoryCustomizer; |
| | | import org.springframework.core.task.VirtualThreadTaskExecutor; |
| | | |
| | | /** |
| | | * Undertow èªå®ä¹é
ç½® |
| | |
| | | WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); |
| | | webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512)); |
| | | deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); |
| | | // 使ç¨èæçº¿ç¨ |
| | | if (SpringUtils.isVirtual()) { |
| | | VirtualThreadTaskExecutor executor = new VirtualThreadTaskExecutor("undertow-"); |
| | | deploymentInfo.setExecutor(executor); |
| | | deploymentInfo.setAsyncExecutor(executor); |
| | | } |
| | | }); |
| | | } |
| | | |
ÎļþÃû´Ó ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java ÐÞ¸Ä |
| | |
| | | package org.dromara.common.security.handler; |
| | | package org.dromara.common.web.handler; |
| | | |
| | | import cn.dev33.satoken.exception.NotLoginException; |
| | | import cn.dev33.satoken.exception.NotPermissionException; |
| | | import cn.dev33.satoken.exception.NotRoleException; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.http.HttpStatus; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; |
| | | import org.springframework.web.servlet.NoHandlerFoundException; |
| | | |
| | | /** |
| | | * å
¨å±å¼å¸¸å¤çå¨ |
| | |
| | | public class GlobalExceptionHandler { |
| | | |
| | | /** |
| | | * æéç å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotPermissionException.class) |
| | | public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',æéç æ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * è§è²æéå¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(NotRoleException.class) |
| | | public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',è§è²æéæ ¡éªå¤±è´¥'{}'", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_FORBIDDEN, "没æè®¿é®æéï¼è¯·è系管çåææ"); |
| | | } |
| | | |
| | | /** |
| | | * 认è¯å¤±è´¥ |
| | | */ |
| | | @ExceptionHandler(NotLoginException.class) |
| | | public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',认è¯å¤±è´¥'{}',æ æ³è®¿é®ç³»ç»èµæº", requestURI, e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº"); |
| | | } |
| | | |
| | | /** |
| | | * è¯·æ±æ¹å¼ä¸æ¯æ |
| | | */ |
| | | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) |
| | |
| | | HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}',䏿¯æ'{}'请æ±", requestURI, e.getMethod()); |
| | | return R.fail(e.getMessage()); |
| | | return R.fail(HttpStatus.HTTP_BAD_METHOD, e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¾ä¸å°è·¯ç± |
| | | */ |
| | | @ExceptionHandler(NoHandlerFoundException.class) |
| | | public R<Void> handleNoHandlerFoundException(NoHandlerFoundException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请æ±å°å'{}'ä¸åå¨.", requestURI); |
| | | return R.fail(HttpStatus.HTTP_NOT_FOUND, e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * æ¦æªæªç¥çè¿è¡æ¶å¼å¸¸ |
| | | */ |
| | | @ExceptionHandler(RuntimeException.class) |
| | |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import com.alibaba.ttl.TransmittableThreadLocal; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.web.filter.RepeatedlyRequestWrapper; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.web.filter.RepeatedlyRequestWrapper; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.servlet.HandlerInterceptor; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | |
| | | |
| | | private final String prodProfile = "prod"; |
| | | |
| | | private final TransmittableThreadLocal<StopWatch> invokeTimeTL = new TransmittableThreadLocal<>(); |
| | | private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>(); |
| | | |
| | | @Override |
| | | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
| | |
| | | } |
| | | |
| | | StopWatch stopWatch = new StopWatch(); |
| | | invokeTimeTL.set(stopWatch); |
| | | KEY_CACHE.set(stopWatch); |
| | | stopWatch.start(); |
| | | } |
| | | return true; |
| | |
| | | @Override |
| | | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { |
| | | if (!prodProfile.equals(SpringUtils.getActiveProfile())) { |
| | | StopWatch stopWatch = invokeTimeTL.get(); |
| | | StopWatch stopWatch = KEY_CACHE.get(); |
| | | stopWatch.stop(); |
| | | log.info("[PLUS]ç»æè¯·æ± => URL[{}],èæ¶:[{}]毫ç§", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); |
| | | invokeTimeTL.remove(); |
| | | KEY_CACHE.remove(); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | <modules> |
| | | <module>ruoyi-monitor-admin</module> |
| | | <module>ruoyi-powerjob-server</module> |
| | | <module>ruoyi-snailjob-server</module> |
| | | </modules> |
| | | |
| | | </project> |
| | |
| | | |
| | | ADD ./target/ruoyi-monitor-admin.jar ./app.jar |
| | | |
| | | ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar app.jar \ |
| | | -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} |
| | | ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \ |
| | | -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \ |
| | | -jar app.jar |
| | |
| | | import de.codecentric.boot.admin.server.config.EnableAdminServer; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| | | import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; |
| | | import org.springframework.boot.task.TaskExecutorBuilder; |
| | | import org.springframework.boot.task.ThreadPoolTaskExecutorBuilder; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.Lazy; |
| | |
| | | @Lazy |
| | | @Bean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) |
| | | @ConditionalOnMissingBean(Executor.class) |
| | | public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) { |
| | | public ThreadPoolTaskExecutor applicationTaskExecutor(ThreadPoolTaskExecutorBuilder builder) { |
| | | return builder.build(); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #FROM findepi/graalvm:java17-native |
| | | FROM openjdk:17.0.2-oraclelinux8 |
| | | |
| | | MAINTAINER Lion Li |
| | | |
| | | RUN mkdir -p /ruoyi/snailjob/logs |
| | | |
| | | WORKDIR /ruoyi/snailjob |
| | | |
| | | ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Xms512m -Xmx1024m" |
| | | |
| | | EXPOSE 8800 |
| | | EXPOSE 1788 |
| | | |
| | | ADD ./target/ruoyi-snailjob-server.jar ./app.jar |
| | | |
| | | ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \ |
| | | -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \ |
| | | -jar app.jar |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?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"> |
| | | <parent> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-extend</artifactId> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <packaging>jar</packaging> |
| | | <artifactId>ruoyi-snailjob-server</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.aizuda</groupId> |
| | | <artifactId>snail-job-server-starter</artifactId> |
| | | <version>${snailjob.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>de.codecentric</groupId> |
| | | <artifactId>spring-boot-admin-starter-client</artifactId> |
| | | <version>${spring-boot-admin.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <finalName>${project.artifactId}</finalName> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | <version>${spring-boot.version}</version> |
| | | <executions> |
| | | <execution> |
| | | <goals> |
| | | <goal>repackage</goal> |
| | | </goals> |
| | | </execution> |
| | | </executions> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.snailjob; |
| | | |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | |
| | | /** |
| | | * SnailJob Server å¯å¨ç¨åº |
| | | * |
| | | * @author opensnail |
| | | * @date 2024-05-17 |
| | | */ |
| | | @SpringBootApplication |
| | | public class SnailJobServerApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(com.aizuda.snailjob.server.SnailJobServerApplication.class, args); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | spring: |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: root |
| | | hikari: |
| | | connection-timeout: 30000 |
| | | validation-timeout: 5000 |
| | | minimum-idle: 10 |
| | | maximum-pool-size: 20 |
| | | idle-timeout: 600000 |
| | | max-lifetime: 900000 |
| | | keepaliveTime: 30000 |
| | | |
| | | --- # snail-job æå¡ç«¯é
ç½® |
| | | snail-job: |
| | | # æåéè¯æ°æ®çæ¯æ¹æ¬¡çå¤§å° |
| | | retry-pull-page-size: 1000 |
| | | # æåéè¯æ°æ®çæ¯æ¹æ¬¡çå¤§å° |
| | | job-pull-page-size: 1000 |
| | | # æå¡ç«¯nettyç«¯å£ |
| | | netty-port: 1788 |
| | | # ä¸ä¸ªå®¢æ·ç«¯æ¯ç§æå¤æ¥æ¶çéè¯æ°éæä»¤ |
| | | limiter: 1000 |
| | | # å·æ®µæ¨¡å¼ä¸æ¥é¿é
ç½® |
| | | step: 100 |
| | | # æ¥å¿ä¿åæ¶é´(åä½: day) |
| | | log-storage: 90 |
| | | # åè°é
ç½® |
| | | callback: |
| | | #åè°æå¤§æ§è¡æ¬¡æ° |
| | | max-count: 288 |
| | | #é´éæ¶é´ |
| | | trigger-interval: 900 |
| | | retry-max-pull-count: 10 |
| | | |
| | | --- # çæ§ä¸å¿é
ç½® |
| | | spring.boot.admin.client: |
| | | # å¢å 客æ·ç«¯å¼å
³ |
| | | enabled: true |
| | | url: http://localhost:9090/admin |
| | | instance: |
| | | service-host-type: IP |
| | | username: ruoyi |
| | | password: 123456 |
¶Ô±ÈÐÂÎļþ |
| | |
| | | spring: |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: root |
| | | hikari: |
| | | connection-timeout: 30000 |
| | | validation-timeout: 5000 |
| | | minimum-idle: 10 |
| | | maximum-pool-size: 20 |
| | | idle-timeout: 600000 |
| | | max-lifetime: 900000 |
| | | keepaliveTime: 30000 |
| | | |
| | | --- # snail-job æå¡ç«¯é
ç½® |
| | | snail-job: |
| | | # æåéè¯æ°æ®çæ¯æ¹æ¬¡çå¤§å° |
| | | retry-pull-page-size: 1000 |
| | | # æåéè¯æ°æ®çæ¯æ¹æ¬¡çå¤§å° |
| | | job-pull-page-size: 1000 |
| | | # æå¡ç«¯ netty ç«¯å£ |
| | | netty-port: 1788 |
| | | # ä¸ä¸ªå®¢æ·ç«¯æ¯ç§æå¤æ¥æ¶çéè¯æ°éæä»¤ |
| | | limiter: 1000 |
| | | # å·æ®µæ¨¡å¼ä¸æ¥é¿é
ç½® |
| | | step: 100 |
| | | # æ¥å¿ä¿åæ¶é´(åä½: day) |
| | | log-storage: 90 |
| | | # åè°é
ç½® |
| | | callback: |
| | | #åè°æå¤§æ§è¡æ¬¡æ° |
| | | max-count: 288 |
| | | #é´éæ¶é´ |
| | | trigger-interval: 900 |
| | | retry-max-pull-count: 10 |
| | | |
| | | --- # çæ§ä¸å¿é
ç½® |
| | | spring.boot.admin.client: |
| | | # å¢å 客æ·ç«¯å¼å
³ |
| | | enabled: true |
| | | url: http://localhost:9090/admin |
| | | instance: |
| | | service-host-type: IP |
| | | username: ruoyi |
| | | password: 123456 |
¶Ô±ÈÐÂÎļþ |
| | |
| | | server: |
| | | port: 8800 |
| | | servlet: |
| | | context-path: /snail-job |
| | | |
| | | spring: |
| | | application: |
| | | name: ruoyi-snailjob-server |
| | | profiles: |
| | | active: @profiles.active@ |
| | | web: |
| | | resources: |
| | | static-locations: classpath:admin/ |
| | | |
| | | mybatis-plus: |
| | | typeAliasesPackage: com.aizuda.snailjob.template.datasource.persistence.po |
| | | global-config: |
| | | db-config: |
| | | where-strategy: NOT_EMPTY |
| | | capital-mode: false |
| | | logic-delete-value: 1 |
| | | logic-not-delete-value: 0 |
| | | configuration: |
| | | map-underscore-to-camel-case: true |
| | | cache-enabled: true |
| | | |
| | | logging: |
| | | config: classpath:logback-plus.xml |
| | | |
| | | management: |
| | | endpoints: |
| | | web: |
| | | exposure: |
| | | include: '*' |
| | | endpoint: |
| | | health: |
| | | show-details: ALWAYS |
| | | logfile: |
| | | external-file: ./logs/ruoyi-snailjob-server/console.log |
¶Ô±ÈÐÂÎļþ |
| | |
| | | Application Version: ${revision} |
| | | Spring Boot Version: ${spring-boot.version} |
| | | _ _ _ _ |
| | | (_) (_) | | |
| | | ___ _ __ __ _ _| |_ ___ | |__ ______ ___ ___ _ ____ _____ _ __ |
| | | / __| '_ \ / _` | | | |/ _ \| '_ \______/ __|/ _ \ '__\ \ / / _ \ '__| |
| | | \__ \ | | | (_| | | | | (_) | |_) | \__ \ __/ | \ V / __/ | |
| | | |___/_| |_|\__,_|_|_| |\___/|_.__/ |___/\___|_| \_/ \___|_| |
| | | _/ | |
| | | |__/ |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <configuration> |
| | | <property name="log.path" value="./logs/ruoyi-snailjob-server" /> |
| | | <property name="console.log.pattern" |
| | | value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> |
| | | <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/> |
| | | |
| | | |
| | | <!-- æ§å¶å°è¾åº --> |
| | | <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder> |
| | | <pattern>${console.log.pattern}</pattern> |
| | | <charset>utf-8</charset> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- æ§å¶å°è¾åº --> |
| | | <appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <file>${log.path}/console.log</file> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <!-- æ¥å¿æä»¶åæ ¼å¼ --> |
| | | <fileNamePattern>${log.path}/console.%d{yyyy-MM-dd}.log</fileNamePattern> |
| | | <!-- æ¥å¿æå¤§ 1天 --> |
| | | <maxHistory>1</maxHistory> |
| | | </rollingPolicy> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | <charset>utf-8</charset> |
| | | </encoder> |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <!-- è¿æ»¤ççº§å« --> |
| | | <level>INFO</level> |
| | | </filter> |
| | | </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> |
| | | <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> |
| | | <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> |
| | | |
| | | <appender name ="async_info" class= "ch.qos.logback.classic.AsyncAppender"> |
| | | <discardingThreshold >100</discardingThreshold> |
| | | <queueSize>1024</queueSize> |
| | | <appender-ref ref ="file_info"/> |
| | | </appender> |
| | | |
| | | <appender name ="async_error" class= "ch.qos.logback.classic.AsyncAppender"> |
| | | <discardingThreshold >100</discardingThreshold> |
| | | <queueSize>1024</queueSize> |
| | | <appender-ref ref ="file_error"/> |
| | | </appender> |
| | | |
| | | <!-- SnailJob appender --> |
| | | <appender name="snail_log_server_appender" class="com.aizuda.snailjob.server.common.appender.SnailJobServerLogbackAppender"> |
| | | </appender> |
| | | |
| | | <!-- æ§å¶å°è¾åºæ¥å¿çº§å« --> |
| | | <root level="info"> |
| | | <appender-ref ref="console" /> |
| | | <appender-ref ref="async_info" /> |
| | | <appender-ref ref="async_error" /> |
| | | <appender-ref ref="snail_log_server_appender" /> |
| | | </root> |
| | | </configuration> |
| | |
| | | <module>ruoyi-generator</module> |
| | | <module>ruoyi-job</module> |
| | | <module>ruoyi-system</module> |
| | | <module>ruoyi-workflow</module> |
| | | </modules> |
| | | |
| | | <artifactId>ruoyi-modules</artifactId> |
| | |
| | | import org.dromara.sms4j.api.SmsBlend; |
| | | import org.dromara.sms4j.api.entity.SmsResponse; |
| | | import org.dromara.sms4j.core.factory.SmsFactory; |
| | | import org.dromara.sms4j.provider.enumerate.SupplierType; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | |
| | | @RestController |
| | | @RequestMapping("/demo/sms") |
| | | public class SmsController { |
| | | |
| | | /** |
| | | * åéçä¿¡Aliyun |
| | | * |
| | |
| | | public R<Object> sendAliyun(String phones, String templateId) { |
| | | LinkedHashMap<String, String> map = new LinkedHashMap<>(1); |
| | | map.put("code", "1234"); |
| | | SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); |
| | | SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
| | | SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map); |
| | | return R.ok(smsResponse); |
| | | } |
| | |
| | | LinkedHashMap<String, String> map = new LinkedHashMap<>(1); |
| | | // map.put("2", "æµè¯æµè¯"); |
| | | map.put("1", "1234"); |
| | | SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.TENCENT); |
| | | SmsBlend smsBlend = SmsFactory.getSmsBlend("config2"); |
| | | SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map); |
| | | return R.ok(smsResponse); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å é»åå |
| | | * |
| | | * @param phone ææºå· |
| | | */ |
| | | @GetMapping("/addBlacklist") |
| | | public R<Object> addBlacklist(String phone){ |
| | | SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
| | | smsBlend.joinInBlacklist(phone); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * ç§»é¤é»åå |
| | | * |
| | | * @param phone ææºå· |
| | | */ |
| | | @GetMapping("/removeBlacklist") |
| | | public R<Object> removeBlacklist(String phone){ |
| | | SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
| | | smsBlend.removeFromBlacklist(phone); |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * åæè¿° |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String columnComment; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * æ¯å¦ä¸»é®ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isPk; |
| | | |
| | | /** |
| | | * æ¯å¦èªå¢ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isIncrement; |
| | | |
| | | /** |
| | | * æ¯å¦å¿
å¡«ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isRequired; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºæå
¥å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isInsert; |
| | | |
| | | /** |
| | | * æ¯å¦ç¼è¾å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isEdit; |
| | | |
| | | /** |
| | | * æ¯å¦åè¡¨åæ®µï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isList; |
| | | |
| | | /** |
| | | * æ¯å¦æ¥è¯¢å段ï¼1æ¯ï¼ |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR) |
| | | @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) |
| | | private String isQuery; |
| | | |
| | | /** |
| | |
| | | select table_name, table_comment, create_time, update_time |
| | | from information_schema.tables |
| | | where table_schema = (select database()) |
| | | AND table_name NOT LIKE 'pj_%' AND table_name NOT LIKE 'gen_%' |
| | | AND table_name NOT LIKE 'sj_%' AND table_name NOT LIKE 'gen_%' |
| | | AND table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' |
| | | <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> |
| | | AND table_name NOT IN |
| | | <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> |
| | |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'pj_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' |
| | | <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> |
| | | AND lower(dt.table_name) NOT IN |
| | | <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> |
| | |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'pj_%' AND table_name NOT LIKE 'gen_%' |
| | | where table_name NOT LIKE 'sj_%' AND table_name NOT LIKE 'gen_%' |
| | | AND table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' |
| | | <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> |
| | | AND table_name NOT IN |
| | | <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> |
| | |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'pj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' |
| | | <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> |
| | | AND D.NAME NOT IN |
| | | <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> |
| | |
| | | <select id="selectDbTableListByNames" resultMap="GenTableResult"> |
| | | <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select table_name, table_comment, create_time, update_time from information_schema.tables |
| | | where table_name NOT LIKE 'pj_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) |
| | | where table_schema = (select database()) |
| | | and table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' |
| | | and table_name in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'pj_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | and dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | and dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' |
| | | and lower(dt.table_name) in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'pj_%' and table_name NOT LIKE 'gen_%' |
| | | where table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name NOT LIKE 'act_%' and table_name NOT LIKE 'flw_%' |
| | | and table_name in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'pj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' |
| | | AND D.NAME in |
| | | <foreach collection="array" item="name" open="(" separator="," close=")"> |
| | | #{name} |
| | |
| | | <select id="selectTableByName" parameterType="String" resultMap="GenTableResult"> |
| | | <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> |
| | | select table_name, table_comment, create_time, update_time from information_schema.tables |
| | | where table_name NOT LIKE 'pj_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) |
| | | where table_schema = (select database()) |
| | | and table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' |
| | | and table_name = #{tableName} |
| | | </if> |
| | | <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()"> |
| | |
| | | where dt.table_name = dtc.table_name |
| | | and dt.table_name = uo.object_name |
| | | and uo.object_type = 'TABLE' |
| | | AND dt.table_name NOT LIKE 'pj_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' |
| | | AND dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' |
| | | AND dt.table_name NOT IN (select table_name from gen_table) |
| | | and lower(dt.table_name) = #{tableName} |
| | | </if> |
| | |
| | | AND n.nspname = 'public'::name |
| | | AND n.nspname <![CDATA[ <> ]]> ''::name |
| | | ) list_table |
| | | where table_name NOT LIKE 'pj_%' and table_name NOT LIKE 'gen_%' |
| | | where table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' |
| | | and table_name NOT LIKE 'act_%' and table_name NOT LIKE 'flw_%' |
| | | and table_name = #{tableName} |
| | | </if> |
| | | <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()"> |
| | |
| | | FROM SYSOBJECTS D |
| | | INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID |
| | | AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' |
| | | AND D.NAME NOT LIKE 'pj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' |
| | | AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' |
| | | AND D.NAME = #{tableName} |
| | | </if> |
| | | </select> |
| | |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import ${packageName}.domain.bo.${ClassName}Bo; |
| | | import ${packageName}.service.I${ClassName}Service; |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | #elseif($table.tree) |
| | | #end |
| | |
| | | */ |
| | | @SaCheckPermission("${permissionPrefix}:list") |
| | | @GetMapping("/list") |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) { |
| | | return ${className}Service.queryPageList(bo, pageQuery); |
| | | } |
| | |
| | | package ${packageName}.service; |
| | | |
| | | import ${packageName}.domain.${ClassName}; |
| | | import ${packageName}.domain.vo.${ClassName}Vo; |
| | | import ${packageName}.domain.bo.${ClassName}Bo; |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | #end |
| | |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName} |
| | | * |
| | | * @param ${pkColumn.javaField} ä¸»é® |
| | | * @return ${functionName} |
| | | */ |
| | | ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}); |
| | | |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | * å页æ¥è¯¢${functionName}å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @param pageQuery å页忰 |
| | | * @return ${functionName}å页å表 |
| | | */ |
| | | TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery); |
| | | #end |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | * æ¥è¯¢ç¬¦åæ¡ä»¶ç${functionName}å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @return ${functionName}å表 |
| | | */ |
| | | List<${ClassName}Vo> queryList(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * æ°å¢${functionName} |
| | | * |
| | | * @param bo ${functionName} |
| | | * @return æ¯å¦æ°å¢æå |
| | | */ |
| | | Boolean insertByBo(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹${functionName} |
| | | * |
| | | * @param bo ${functionName} |
| | | * @return æ¯å¦ä¿®æ¹æå |
| | | */ |
| | | Boolean updateByBo(${ClassName}Bo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤${functionName}ä¿¡æ¯ |
| | | * |
| | | * @param ids å¾
å é¤ç主é®éå |
| | | * @param isValid æ¯å¦è¿è¡æææ§æ ¡éª |
| | | * @return æ¯å¦å 餿å |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid); |
| | | } |
| | |
| | | |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName} |
| | | * |
| | | * @param ${pkColumn.javaField} ä¸»é® |
| | | * @return ${functionName} |
| | | */ |
| | | @Override |
| | | public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){ |
| | | return baseMapper.selectVoById(${pkColumn.javaField}); |
| | | } |
| | | |
| | | #if($table.crud || $table.sub) |
| | | #if($table.crud) |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | * å页æ¥è¯¢${functionName}å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @param pageQuery å页忰 |
| | | * @return ${functionName}å页å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery) { |
| | |
| | | #end |
| | | |
| | | /** |
| | | * æ¥è¯¢${functionName}å表 |
| | | * æ¥è¯¢ç¬¦åæ¡ä»¶ç${functionName}å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @return ${functionName}å表 |
| | | */ |
| | | @Override |
| | | public List<${ClassName}Vo> queryList(${ClassName}Bo bo) { |
| | |
| | | |
| | | /** |
| | | * æ°å¢${functionName} |
| | | * |
| | | * @param bo ${functionName} |
| | | * @return æ¯å¦æ°å¢æå |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(${ClassName}Bo bo) { |
| | |
| | | |
| | | /** |
| | | * ä¿®æ¹${functionName} |
| | | * |
| | | * @param bo ${functionName} |
| | | * @return æ¯å¦ä¿®æ¹æå |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(${ClassName}Bo bo) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤${functionName} |
| | | * æ ¡éªå¹¶æ¹éå é¤${functionName}ä¿¡æ¯ |
| | | * |
| | | * @param ids å¾
å é¤ç主é®éå |
| | | * @param isValid æ¯å¦è¿è¡æææ§æ ¡éª |
| | | * @return æ¯å¦å 餿å |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) { |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | #foreach($column in $columns) |
| | | #if($column.query) |
| | | #set($dictType=$column.dictType) |
| | |
| | | #set($comment=$column.columnComment) |
| | | #end |
| | | #if($column.htmlType == "input" || $column.htmlType == "textarea") |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-input v-model="queryParams.${column.javaField}" placeholder="请è¾å
¥${comment}" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-input v-model="queryParams.${column.javaField}" placeholder="请è¾å
¥${comment}" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option |
| | | v-for="dict in ${dictType}" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option label="è¯·éæ©åå
¸çæ" value="" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option label="è¯·éæ©åå
¸çæ" value="" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-date-picker clearable |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-date-picker clearable |
| | | v-model="queryParams.${column.javaField}" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="éæ©${comment}" |
| | | /> |
| | | </el-form-item> |
| | | /> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") |
| | | <el-form-item label="${comment}" style="width: 308px"> |
| | | <el-date-picker |
| | | <el-form-item label="${comment}" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange${AttrName}" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | /> |
| | | </el-form-item> |
| | | /> |
| | | </el-form-item> |
| | | #end |
| | | #end |
| | | #end |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | |
| | | </el-row> |
| | | </template> |
| | | <el-table |
| | | ref="${businessName}TableRef" |
| | | v-loading="loading" |
| | | :data="${businessName}List" |
| | | row-key="${treeCode}" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | ref="${businessName}TableRef" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | > |
| | | #foreach($column in $columns) |
| | | #set($javaField=$column.javaField) |
| | |
| | | v-for="dict in ${dictType}" |
| | | :key="dict.value" |
| | | #if($column.javaType == "Integer" || $column.javaType == "Long") |
| | | :label="parseInt(dict.value)" |
| | | :value="parseInt(dict.value)" |
| | | #else |
| | | :label="dict.value" |
| | | :value="dict.value" |
| | | #end |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | |
| | | #elseif($column.htmlType == "radio" && $dictType) |
| | | <el-form-item label="${comment}" prop="${field}"> |
| | | <el-radio-group v-model="form.${field}"> |
| | | <el-radio label="1">è¯·éæ©åå
¸çæ</el-radio> |
| | | <el-radio value="1">è¯·éæ©åå
¸çæ</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime") |
| | |
| | | reset(); |
| | | getTreeselect(); |
| | | if (row != null && row.${treeCode}) { |
| | | form.value.${treeParentCode} = row.${treeCode}; |
| | | form.value.${treeParentCode} = row.${treeCode}; |
| | | } else { |
| | | form.value.${treeParentCode} = 0; |
| | | form.value.${treeParentCode} = 0; |
| | | } |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å ${functionName}"; |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | #foreach($column in $columns) |
| | | #if($column.query) |
| | | #set($dictType=$column.dictType) |
| | |
| | | #set($comment=$column.columnComment) |
| | | #end |
| | | #if($column.htmlType == "input" || $column.htmlType == "textarea") |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-input v-model="queryParams.${column.javaField}" placeholder="请è¾å
¥${comment}" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-input v-model="queryParams.${column.javaField}" placeholder="请è¾å
¥${comment}" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option |
| | | v-for="dict in ${dictType}" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable > |
| | | <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable> |
| | | <el-option label="è¯·éæ©åå
¸çæ" value="" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-select v-model="queryParams.${column.javaField}" placeholder="è¯·éæ©${comment}" clearable > |
| | | <el-option label="è¯·éæ©åå
¸çæ" value="" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-date-picker clearable |
| | | v-model="queryParams.${column.javaField}" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©${comment}" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="${comment}" prop="${column.javaField}"> |
| | | <el-date-picker clearable |
| | | v-model="queryParams.${column.javaField}" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©${comment}" |
| | | /> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") |
| | | <el-form-item label="${comment}" style="width: 308px"> |
| | | <el-date-picker |
| | | <el-form-item label="${comment}" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange${AttrName}" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | /> |
| | | </el-form-item> |
| | | /> |
| | | </el-form-item> |
| | | #end |
| | | #end |
| | | #end |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹${functionName}å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | |
| | | <el-form-item label="${comment}" prop="${field}"> |
| | | <el-radio-group v-model="form.${field}"> |
| | | <el-radio |
| | | v-for="dict in ${dictType}" |
| | | :key="dict.value" |
| | | v-for="dict in ${dictType}" |
| | | :key="dict.value" |
| | | #if($column.javaType == "Integer" || $column.javaType == "Long") |
| | | :label="parseInt(dict.value)" |
| | | :value="parseInt(dict.value)" |
| | | #else |
| | | :label="dict.value" |
| | | :value="dict.value" |
| | | #end |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | |
| | | #elseif($column.htmlType == "radio" && $dictType) |
| | | <el-form-item label="${comment}" prop="${field}"> |
| | | <el-radio-group v-model="form.${field}"> |
| | | <el-radio label="1">è¯·éæ©åå
¸çæ</el-radio> |
| | | <el-radio value="1">è¯·éæ©åå
¸çæ</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | #elseif($column.htmlType == "datetime") |
| | |
| | | } else { |
| | | await add${BusinessName}(form.value).finally(() => buttonLoading.value = false); |
| | | } |
| | | proxy?.#[[$modal]]#.msgSuccess("ä¿®æ¹æå"); |
| | | proxy?.#[[$modal]]#.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | await getList(); |
| | | } |
| | |
| | | /** |
| | | * æ¼ç¤ºç¨ä¾ |
| | | * copy from https://github.com/PowerJob/PowerJob/tree/master/powerjob-worker-samples/src/main/java/tech/powerjob/samples |
| | | */ |
| | | |
| | | package org.dromara.job; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.job.snailjob; |
| | | |
| | | import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; |
| | | import com.aizuda.snailjob.client.job.core.dto.JobArgs; |
| | | import com.aizuda.snailjob.client.model.ExecuteResult; |
| | | import com.aizuda.snailjob.common.core.util.JsonUtil; |
| | | import com.aizuda.snailjob.common.log.SnailJobLog; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * @author opensnail |
| | | * @date 2024-05-17 |
| | | */ |
| | | @Component |
| | | @JobExecutor(name = "testJobExecutor") |
| | | public class TestAnnoJobExecutor { |
| | | |
| | | public ExecuteResult jobExecute(JobArgs jobArgs) { |
| | | SnailJobLog.LOCAL.info("testJobExecutor. jobArgs:{}", JsonUtil.toJsonString(jobArgs)); |
| | | SnailJobLog.REMOTE.info("testJobExecutor. jobArgs:{}", JsonUtil.toJsonString(jobArgs)); |
| | | return ExecuteResult.success("æµè¯æå"); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.job.snailjob; |
| | | |
| | | import com.aizuda.snailjob.client.job.core.dto.JobArgs; |
| | | import com.aizuda.snailjob.client.job.core.executor.AbstractJobExecutor; |
| | | import com.aizuda.snailjob.client.model.ExecuteResult; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * @author opensnail |
| | | * @date 2024-05-17 |
| | | */ |
| | | @Component |
| | | public class TestClassJobExecutor extends AbstractJobExecutor { |
| | | |
| | | @Override |
| | | protected ExecuteResult doJobExecute(JobArgs jobArgs) { |
| | | return ExecuteResult.success("TestJobExecutoræµè¯æå"); |
| | | } |
| | | } |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * å¨çº¿ç¨æ·çæ§ |
| | |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åç¨æ·ç»å½å¨çº¿è®¾å¤ |
| | | */ |
| | | @GetMapping() |
| | | public TableDataInfo<SysUserOnline> getInfo() { |
| | | // è·åæå®è´¦å· id ç token éå |
| | | List<String> tokenIds = StpUtil.getTokenValueListByLoginId(StpUtil.getLoginIdAsString()); |
| | | List<UserOnlineDTO> userOnlineDTOList = tokenIds.stream() |
| | | .filter(token -> StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) >= -1) |
| | | .map(token -> (UserOnlineDTO) RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token)) |
| | | .collect(Collectors.toList()); |
| | | //å¤å¶åå¤ç SysUserOnline 对象å表 |
| | | Collections.reverse(userOnlineDTOList); |
| | | userOnlineDTOList.removeAll(Collections.singleton(null)); |
| | | List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); |
| | | return TableDataInfo.build(userOnlineList); |
| | | } |
| | | |
| | | /** |
| | | * 强éå½åå¨çº¿è®¾å¤ |
| | | * |
| | | * @param tokenId tokenå¼ |
| | | */ |
| | | @Log(title = "å¨çº¿è®¾å¤", businessType = BusinessType.FORCE) |
| | | @PostMapping("/{tokenId}") |
| | | public R<Void> remove(@PathVariable("tokenId") String tokenId) { |
| | | try { |
| | | // è·åæå®è´¦å· id ç token éå |
| | | List<String> keys = StpUtil.getTokenValueListByLoginId(StpUtil.getLoginIdAsString()); |
| | | keys.stream() |
| | | .filter(key -> key.equals(tokenId)) |
| | | .findFirst() |
| | | .ifPresent(key -> StpUtil.kickoutByTokenValue(tokenId)); |
| | | } catch (NotLoginException ignored) { |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| | |
| | | @Log(title = "客æ·ç«¯ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/changeStatus") |
| | | public R<Void> changeStatus(@RequestBody SysClientBo bo) { |
| | | return toAjax(sysClientService.updateUserStatus(bo.getId(), bo.getStatus())); |
| | | return toAjax(sysClientService.updateUserStatus(bo.getClientId(), bo.getStatus())); |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.convert.Convert; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | |
| | | import org.dromara.system.domain.bo.SysDeptBo; |
| | | import org.dromara.system.domain.vo.SysDeptVo; |
| | | import org.dromara.system.service.ISysDeptService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | public R<Void> add(@Validated @RequestBody SysDeptBo dept) { |
| | | if (!deptService.checkDeptNameUnique(dept)) { |
| | | return R.fail("æ°å¢é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨åç§°å·²åå¨"); |
| | | } else if (StringUtils.isNotBlank(dept.getDeptCategory()) && !deptService.checkDeptCategoryUnique(dept)) { |
| | | return R.fail("æ°å¢é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨ç±»å«ç¼ç å·²åå¨"); |
| | | } |
| | | return toAjax(deptService.insertDept(dept)); |
| | | } |
| | |
| | | deptService.checkDeptDataScope(deptId); |
| | | if (!deptService.checkDeptNameUnique(dept)) { |
| | | return R.fail("ä¿®æ¹é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨åç§°å·²åå¨"); |
| | | } else if (StringUtils.isNotBlank(dept.getDeptCategory()) && !deptService.checkDeptCategoryUnique(dept)) { |
| | | return R.fail("ä¿®æ¹é¨é¨'" + dept.getDeptName() + "'失败ï¼é¨é¨ç±»å«ç¼ç å·²åå¨"); |
| | | } else if (dept.getParentId().equals(deptId)) { |
| | | return R.fail("ä¿®æ¹é¨é¨'" + dept.getDeptName() + "'失败ï¼ä¸çº§é¨é¨ä¸è½æ¯èªå·±"); |
| | | } else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())) { |
| | |
| | | deptService.checkDeptDataScope(deptId); |
| | | return toAjax(deptService.deleteDeptById(deptId)); |
| | | } |
| | | |
| | | /** |
| | | * è·åé¨é¨éæ©æ¡å表 |
| | | * |
| | | * @param deptIds é¨é¨ID串 |
| | | */ |
| | | @SaCheckPermission("system:dept:query") |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysDeptVo>> optionselect(@RequestParam(required = false) Long[] deptIds) { |
| | | return R.ok(deptService.selectDeptByIds(deptIds == null ? null : List.of(deptIds))); |
| | | } |
| | | |
| | | } |
| | |
| | | @Log(title = "åå
¸æ°æ®", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public R<Void> add(@Validated @RequestBody SysDictDataBo dict) { |
| | | if (!dictDataService.checkDictDataUnique(dict)) { |
| | | return R.fail("æ°å¢åå
¸æ°æ®'" + dict.getDictValue() + "'失败ï¼åå
¸é®å¼å·²åå¨"); |
| | | } |
| | | dictDataService.insertDictData(dict); |
| | | return R.ok(); |
| | | } |
| | |
| | | @Log(title = "åå
¸æ°æ®", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) { |
| | | if (!dictDataService.checkDictDataUnique(dict)) { |
| | | return R.fail("ä¿®æ¹åå
¸æ°æ®'" + dict.getDictValue() + "'失败ï¼åå
¸é®å¼å·²åå¨"); |
| | | } |
| | | dictDataService.updateDictData(dict); |
| | | return R.ok(); |
| | | } |
| | |
| | | package org.dromara.system.controller.system; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | |
| | | import org.dromara.system.domain.bo.SysPostBo; |
| | | import org.dromara.system.domain.vo.SysPostVo; |
| | | import org.dromara.system.service.ISysPostService; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | |
| | | /** |
| | | * è·åå²ä½éæ©æ¡å表 |
| | | * |
| | | * @param postIds å²ä½ID串 |
| | | * @param deptId é¨é¨id |
| | | */ |
| | | @SaCheckPermission("system:post:query") |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysPostVo>> optionselect() { |
| | | SysPostBo postBo = new SysPostBo(); |
| | | postBo.setStatus(UserConstants.POST_NORMAL); |
| | | List<SysPostVo> posts = postService.selectPostList(postBo); |
| | | return R.ok(posts); |
| | | public R<List<SysPostVo>> optionselect(@RequestParam(required = false) Long[] postIds, @RequestParam(required = false) Long deptId) { |
| | | List<SysPostVo> list = new ArrayList<>(); |
| | | if (ObjectUtil.isNotNull(deptId)) { |
| | | SysPostBo post = new SysPostBo(); |
| | | post.setDeptId(deptId); |
| | | list = postService.selectPostList(post); |
| | | } else if (postIds != null) { |
| | | list = postService.selectPostByIds(List.of(postIds)); |
| | | } |
| | | return R.ok(list); |
| | | } |
| | | |
| | | } |
| | |
| | | import org.dromara.system.domain.vo.SysOssVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.service.ISysOssService; |
| | | import org.dromara.system.service.ISysRoleService; |
| | | import org.dromara.system.service.ISysUserService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.MediaType; |
| | |
| | | SysUserVo user = userService.selectUserById(LoginHelper.getUserId()); |
| | | ProfileVo profileVo = new ProfileVo(); |
| | | profileVo.setUser(user); |
| | | profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserName())); |
| | | profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserName())); |
| | | profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserId())); |
| | | profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserId())); |
| | | return R.ok(profileVo); |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * è·åè§è²éæ©æ¡å表 |
| | | * |
| | | * @param roleIds è§è²ID串 |
| | | */ |
| | | @SaCheckPermission("system:role:query") |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysRoleVo>> optionselect() { |
| | | return R.ok(roleService.selectRoleAll()); |
| | | public R<List<SysRoleVo>> optionselect(@RequestParam(required = false) Long[] roleIds) { |
| | | return R.ok(roleService.selectRoleByIds(roleIds == null ? null : List.of(roleIds))); |
| | | } |
| | | |
| | | /** |
| | |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.encrypt.annotation.ApiEncrypt; |
| | |
| | | @SaCheckPermission("system:user:export") |
| | | @PostMapping("/export") |
| | | public void export(SysUserBo user, HttpServletResponse response) { |
| | | List<SysUserVo> list = userService.selectUserList(user); |
| | | List<SysUserExportVo> listVo = MapstructUtils.convert(list, SysUserExportVo.class); |
| | | ExcelUtil.exportExcel(listVo, "ç¨æ·æ°æ®", SysUserExportVo.class, response); |
| | | List<SysUserExportVo> list = userService.selectUserExportList(user); |
| | | ExcelUtil.exportExcel(list, "ç¨æ·æ°æ®", SysUserExportVo.class, response); |
| | | } |
| | | |
| | | /** |
| | |
| | | SysUserInfoVo userInfoVo = new SysUserInfoVo(); |
| | | SysRoleBo roleBo = new SysRoleBo(); |
| | | roleBo.setStatus(UserConstants.ROLE_NORMAL); |
| | | SysPostBo postBo = new SysPostBo(); |
| | | postBo.setStatus(UserConstants.POST_NORMAL); |
| | | List<SysRoleVo> roles = roleService.selectRoleList(roleBo); |
| | | userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin())); |
| | | userInfoVo.setPosts(postService.selectPostList(postBo)); |
| | | if (ObjectUtil.isNotNull(userId)) { |
| | | SysUserVo sysUser = userService.selectUserById(userId); |
| | | userInfoVo.setUser(sysUser); |
| | | userInfoVo.setRoleIds(StreamUtils.toList(sysUser.getRoles(), SysRoleVo::getRoleId)); |
| | | userInfoVo.setPostIds(postService.selectPostListByUserId(userId)); |
| | | userInfoVo.setRoleIds(roleService.selectRoleListByUserId(userId)); |
| | | Long deptId = sysUser.getDeptId(); |
| | | if (ObjectUtil.isNotNull(deptId)) { |
| | | SysPostBo postBo = new SysPostBo(); |
| | | postBo.setDeptId(deptId); |
| | | userInfoVo.setPosts(postService.selectPostList(postBo)); |
| | | userInfoVo.setPostIds(postService.selectPostListByUserId(userId)); |
| | | } |
| | | } |
| | | return R.ok(userInfoVo); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·ID串æ¹éè·åç¨æ·åºç¡ä¿¡æ¯ |
| | | * |
| | | * @param userIds ç¨æ·ID串 |
| | | * @param deptId é¨é¨ID |
| | | */ |
| | | @SaCheckPermission("system:user:query") |
| | | @GetMapping("/optionselect") |
| | | public R<List<SysUserVo>> optionselect(@RequestParam(required = false) Long[] userIds, |
| | | @RequestParam(required = false) Long deptId) { |
| | | return R.ok(userService.selectUserByIds(userIds == null ? null : List.of(userIds), deptId)); |
| | | } |
| | | |
| | | /** |
| | | * éç½®å¯ç |
| | | */ |
| | | @ApiEncrypt |
| | |
| | | @SaCheckPermission("system:user:query") |
| | | @GetMapping("/authRole/{userId}") |
| | | public R<SysUserInfoVo> authRole(@PathVariable Long userId) { |
| | | userService.checkUserDataScope(userId); |
| | | SysUserVo user = userService.selectUserById(userId); |
| | | List<SysRoleVo> roles = roleService.selectRolesByUserId(userId); |
| | | List<SysRoleVo> roles = roleService.selectRolesAuthByUserId(userId); |
| | | SysUserInfoVo userInfoVo = new SysUserInfoVo(); |
| | | userInfoVo.setUser(user); |
| | | userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin())); |
| | |
| | | public R<List<SysUserVo>> listByDept(@PathVariable @NotNull Long deptId) { |
| | | return R.ok(userService.selectUserListByDept(deptId)); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | |
| | | import java.io.Serial; |
| | | |
| | |
| | | private String deptName; |
| | | |
| | | /** |
| | | * é¨é¨ç±»å«ç¼ç |
| | | */ |
| | | private String deptCategory; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | private Integer orderNum; |
| | |
| | | public class SysOssConfig extends BaseEntity { |
| | | |
| | | /** |
| | | * 主建 |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "oss_config_id") |
| | | private Long ossConfigId; |
| | |
| | | private Long postId; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * å²ä½ç¼ç |
| | | */ |
| | | private String postCode; |
| | |
| | | private String postName; |
| | | |
| | | /** |
| | | * å²ä½ç±»å«ç¼ç |
| | | */ |
| | | private String postCategory; |
| | | |
| | | /** |
| | | * å²ä½æåº |
| | | */ |
| | | private Integer postSort; |
| | |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | |
| | | @Data |
| | | public class SysUserOnline { |
| | | |
| | |
| | | private String deptName; |
| | | |
| | | /** |
| | | * é¨é¨ç±»å«ç¼ç |
| | | */ |
| | | @Size(min = 0, max = 100, message = "é¨é¨ç±»å«ç¼ç é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String deptCategory; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | @NotNull(message = "æ¾ç¤ºé¡ºåºä¸è½ä¸ºç©º") |
| | |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.core.constant.RegexConstants; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.system.domain.SysDictType; |
| | | |
| | |
| | | */ |
| | | @NotBlank(message = "åå
¸ç±»åä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 100, message = "åå
¸ç±»åç±»åé¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼") |
| | | @Pattern(regexp = RegexConstants.DICTIONARY_TYPE, message = "åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼") |
| | | private String dictType; |
| | | |
| | | /** |
| | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Pattern; |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.core.constant.RegexConstants; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.system.domain.SysMenu; |
| | | |
| | |
| | | */ |
| | | @JsonInclude(JsonInclude.Include.NON_NULL) |
| | | @Size(min = 0, max = 100, message = "æéæ è¯é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | @Pattern(regexp = RegexConstants.PERMISSION_STRING, message = "æéæ è¯å¿
须符å tool:build:list æ ¼å¼") |
| | | private String perms; |
| | | |
| | | /** |
| | |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
| | |
| | | public class SysOssConfigBo extends BaseEntity { |
| | | |
| | | /** |
| | | * 主建 |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主建ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long ossConfigId; |
| | | |
| | | /** |
| | |
| | | private Long postId; |
| | | |
| | | /** |
| | | * é¨é¨idï¼åé¨é¨ï¼ |
| | | */ |
| | | @NotNull(message = "é¨é¨idä¸è½ä¸ºç©º") |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * å½å±é¨é¨idï¼é¨é¨æ ï¼ |
| | | */ |
| | | private Long belongDeptId; |
| | | |
| | | /** |
| | | * å²ä½ç¼ç |
| | | */ |
| | | @NotBlank(message = "å²ä½ç¼ç ä¸è½ä¸ºç©º") |
| | |
| | | @NotBlank(message = "å²ä½åç§°ä¸è½ä¸ºç©º") |
| | | @Size(min = 0, max = 50, message = "å²ä½åç§°é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String postName; |
| | | |
| | | /** |
| | | * å²ä½ç±»å«ç¼ç |
| | | */ |
| | | @Size(min = 0, max = 100, message = "ç±»å«ç¼ç é¿åº¦ä¸è½è¶
è¿{max}个å符") |
| | | private String postCategory; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
| | |
| | | private Long id; |
| | | |
| | | /** |
| | | * çå¯ä¸ID |
| | | * 认è¯å¯ä¸ID |
| | | */ |
| | | @NotBlank(message = "çå¯ä¸IDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | @NotBlank(message = "认è¯å¯ä¸IDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String authId; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * ç¨æ·ç ID |
| | | */ |
| | | @NotBlank(message = "ç¨æ·ç IDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | @NotBlank(message = "ç¨æ·çIDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private Long userId; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private Long roleId; |
| | | |
| | | /** |
| | | * æé¤ä¸æ¥è¯¢çç¨æ·(工使µç¨) |
| | | */ |
| | | private String excludeUserIds; |
| | | |
| | | public SysUserBo(Long userId) { |
| | | this.userId = userId; |
| | | } |
| | |
| | | private String deptName; |
| | | |
| | | /** |
| | | * é¨é¨ç±»å«ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "é¨é¨ç±»å«ç¼ç ") |
| | | private String deptCategory; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | private Integer orderNum; |
| | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 主建 |
| | | * ä¸»é® |
| | | */ |
| | | private Long ossConfigId; |
| | | |
| | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import org.dromara.common.excel.annotation.ExcelDictFormat; |
| | | import org.dromara.common.excel.convert.ExcelDictConvert; |
| | | import org.dromara.system.domain.SysPost; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.dromara.common.excel.annotation.ExcelDictFormat; |
| | | import org.dromara.common.excel.convert.ExcelDictConvert; |
| | | import org.dromara.common.translation.annotation.Translation; |
| | | import org.dromara.common.translation.constant.TransConstant; |
| | | import org.dromara.system.domain.SysPost; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | |
| | | /** |
| | | * å²ä½ä¿¡æ¯è§å¾å¯¹è±¡ sys_post |
| | |
| | | private Long postId; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | @ExcelProperty(value = "é¨é¨id") |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * å²ä½ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "å²ä½ç¼ç ") |
| | |
| | | */ |
| | | @ExcelProperty(value = "å²ä½åç§°") |
| | | private String postName; |
| | | |
| | | /** |
| | | * å²ä½ç±»å«ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "ç±»å«ç¼ç ") |
| | | private String postCategory; |
| | | |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | |
| | | @ExcelProperty(value = "å建æ¶é´") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * é¨é¨å |
| | | */ |
| | | @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "deptId") |
| | | private String deptName; |
| | | |
| | | } |
| | |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AutoMapper(target = SysUserVo.class, convertGenerate = false) |
| | | public class SysUserExportVo implements Serializable { |
| | | |
| | | @Serial |
| | |
| | | /** |
| | | * é¨é¨åç§° |
| | | */ |
| | | @ReverseAutoMapping(target = "deptName", source = "dept.deptName") |
| | | @ExcelProperty(value = "é¨é¨åç§°") |
| | | private String deptName; |
| | | |
| | | /** |
| | | * è´è´£äºº |
| | | */ |
| | | @ReverseAutoMapping(target = "leaderName", source = "dept.leaderName") |
| | | @ExcelProperty(value = "é¨é¨è´è´£äºº") |
| | | private String leaderName; |
| | | |
| | |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * é¨é¨å¯¹è±¡ |
| | | * é¨é¨å |
| | | */ |
| | | private SysDeptVo dept; |
| | | @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "deptId") |
| | | private String deptName; |
| | | |
| | | /** |
| | | * è§è²å¯¹è±¡ |
| | |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id") |
| | | }) |
| | | SysDeptVo selectDeptById(Long deptId); |
| | | long countDeptById(Long deptId); |
| | | |
| | | /** |
| | | * æ ¹æ®è§è²IDæ¥è¯¢é¨é¨æ ä¿¡æ¯ |
| | |
| | | package org.dromara.system.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.dromara.common.mybatis.annotation.DataColumn; |
| | | import org.dromara.common.mybatis.annotation.DataPermission; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.system.domain.SysPost; |
| | | import org.dromara.system.domain.vo.SysPostVo; |
| | |
| | | */ |
| | | public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> { |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDè·åå²ä½éæ©æ¡å表 |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return éä¸å²ä½IDå表 |
| | | */ |
| | | List<Long> selectPostListByUserId(Long userId); |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "create_by") |
| | | }) |
| | | Page<SysPostVo> selectPagePostList(@Param("page") Page<SysPostVo> page, @Param(Constants.WRAPPER) Wrapper<SysPost> queryWrapper); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¨æ·æå±å²ä½ç» |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | List<SysPostVo> selectPostsByUserName(String userName); |
| | | List<SysPostVo> selectPostsByUserId(Long userId); |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.dromara.common.mybatis.annotation.DataColumn; |
| | | import org.dromara.common.mybatis.annotation.DataPermission; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.system.domain.SysRole; |
| | | import org.dromara.system.domain.vo.SysRoleVo; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | */ |
| | | List<SysRoleVo> selectRolePermissionByUserId(Long userId); |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDè·åè§è²éæ©æ¡å表 |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return éä¸è§è²IDå表 |
| | | */ |
| | | List<Long> selectRoleListByUserId(Long userId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢è§è² |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return è§è²å表 |
| | | */ |
| | | List<SysRoleVo> selectRolesByUserName(String userName); |
| | | List<SysRoleVo> selectRolesByUserId(Long userId); |
| | | |
| | | } |
| | |
| | | import org.dromara.common.mybatis.annotation.DataPermission; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysUserExportVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | |
| | | import java.util.List; |
| | |
| | | public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> { |
| | | |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "d.dept_id"), |
| | | @DataColumn(key = "deptName", value = "u.dept_id"), |
| | | @DataColumn(key = "userName", value = "u.user_id") |
| | | }) |
| | | Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); |
| | | |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¡ä»¶å页æ¥è¯¢ç¨æ·å表 |
| | |
| | | @DataColumn(key = "deptName", value = "d.dept_id"), |
| | | @DataColumn(key = "userName", value = "u.user_id") |
| | | }) |
| | | List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); |
| | | List<SysUserExportVo> selectUserExportList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¡ä»¶å页æ¥è¯¢å·²é
ç¨æ·è§è²å表 |
| | |
| | | }) |
| | | Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·åæ¥è¯¢ç¨æ· |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @return ç¨æ·å¯¹è±¡ä¿¡æ¯ |
| | | */ |
| | | SysUserVo selectUserByUserName(String userName); |
| | | |
| | | /** |
| | | * éè¿ææºå·æ¥è¯¢ç¨æ· |
| | | * |
| | | * @param phonenumber ææºå· |
| | | * @return ç¨æ·å¯¹è±¡ä¿¡æ¯ |
| | | */ |
| | | SysUserVo selectUserByPhonenumber(String phonenumber); |
| | | |
| | | /** |
| | | * éè¿é®ç®±æ¥è¯¢ç¨æ· |
| | | * |
| | | * @param email é®ç®± |
| | | * @return ç¨æ·å¯¹è±¡ä¿¡æ¯ |
| | | */ |
| | | SysUserVo selectUserByEmail(String email); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ· |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return ç¨æ·å¯¹è±¡ä¿¡æ¯ |
| | | */ |
| | | @DataPermission({ |
| | | @DataColumn(key = "deptName", value = "d.dept_id"), |
| | | @DataColumn(key = "userName", value = "u.user_id") |
| | | @DataColumn(key = "deptName", value = "dept_id"), |
| | | @DataColumn(key = "userName", value = "user_id") |
| | | }) |
| | | SysUserVo selectUserById(Long userId); |
| | | long countUserById(Long userId); |
| | | |
| | | @Override |
| | | @DataPermission({ |
| | |
| | | /** |
| | | * æ¥è¯¢å®¢æ·ç«¯ä¿¡æ¯åºäºå®¢æ·ç«¯id |
| | | */ |
| | | SysClient queryByClientId(String clientId); |
| | | SysClientVo queryByClientId(String clientId); |
| | | |
| | | /** |
| | | * æ¥è¯¢å®¢æ·ç«¯ç®¡çå表 |
| | |
| | | /** |
| | | * ä¿®æ¹ç¶æ |
| | | */ |
| | | int updateUserStatus(Long id, String status); |
| | | int updateUserStatus(String clientId, String status); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤å®¢æ·ç«¯ç®¡çä¿¡æ¯ |
| | |
| | | SysDeptVo selectDeptById(Long deptId); |
| | | |
| | | /** |
| | | * éè¿é¨é¨ID串æ¥è¯¢é¨é¨ |
| | | * |
| | | * @param deptIds é¨é¨id串 |
| | | * @return é¨é¨åè¡¨ä¿¡æ¯ |
| | | */ |
| | | List<SysDeptVo> selectDeptByIds(List<Long> deptIds); |
| | | |
| | | /** |
| | | * æ ¹æ®IDæ¥è¯¢ææåé¨é¨æ°ï¼æ£å¸¸ç¶æï¼ |
| | | * |
| | | * @param deptId é¨é¨ID |
| | |
| | | boolean checkDeptNameUnique(SysDeptBo dept); |
| | | |
| | | /** |
| | | * æ ¡éªé¨é¨ç±»å«ç¼ç æ¯å¦å¯ä¸ |
| | | * |
| | | * @param dept é¨é¨ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | boolean checkDeptCategoryUnique(SysDeptBo dept); |
| | | |
| | | /** |
| | | * æ ¡éªé¨é¨æ¯å¦ææ°æ®æé |
| | | * |
| | | * @param deptId é¨é¨id |
| | |
| | | * @return ç»æ |
| | | */ |
| | | List<SysDictDataVo> updateDictData(SysDictDataBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªåå
¸é®å¼æ¯å¦å¯ä¸ |
| | | * |
| | | * @param dict åå
¸æ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | boolean checkDictDataUnique(SysDictDataBo dict); |
| | | |
| | | } |
| | |
| | | */ |
| | | TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery); |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®æ°å¢ä¸å¡å¯¹è±¡æå
¥å¯¹è±¡åå¨é
ç½® |
| | | * |
| | | * @param bo 对象åå¨é
ç½®æ°å¢ä¸å¡å¯¹è±¡ |
| | | * @return |
| | | * @return ç»æ |
| | | */ |
| | | Boolean insertByBo(SysOssConfigBo bo); |
| | | |
| | |
| | | * æ ¹æ®ç¼è¾ä¸å¡å¯¹è±¡ä¿®æ¹å¯¹è±¡åå¨é
ç½® |
| | | * |
| | | * @param bo 对象åå¨é
ç½®ç¼è¾ä¸å¡å¯¹è±¡ |
| | | * @return |
| | | * @return ç»æ |
| | | */ |
| | | Boolean updateByBo(SysOssConfigBo bo); |
| | | |
| | |
| | | * |
| | | * @param ids 主é®éå |
| | | * @param isValid æ¯å¦æ ¡éª,true-å é¤åæ ¡éª,false-䏿 ¡éª |
| | | * @return |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | |
| | | */ |
| | | public interface ISysOssService { |
| | | |
| | | /** |
| | | * æ¥è¯¢OSS对象åå¨å表 |
| | | * |
| | | * @param sysOss OSS对象åå¨å页æ¥è¯¢å¯¹è±¡ |
| | | * @param pageQuery å页æ¥è¯¢å®ä½ç±» |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ ¹æ®ä¸ç» ossIds è·å对åºç SysOssVo å表 |
| | | * |
| | | * @param ossIds ä¸ç»æä»¶å¨æ°æ®åºä¸çå¯ä¸æ è¯éå |
| | | * @return å
å« SysOssVo 对象çå表 |
| | | */ |
| | | List<SysOssVo> listByIds(Collection<Long> ossIds); |
| | | |
| | | /** |
| | | * æ ¹æ® ossId ä»ç¼åææ°æ®åºä¸è·å SysOssVo 对象 |
| | | * |
| | | * @param ossId æä»¶å¨æ°æ®åºä¸çå¯ä¸æ è¯ |
| | | * @return SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | */ |
| | | SysOssVo getById(Long ossId); |
| | | |
| | | /** |
| | | * ä¸ä¼ MultipartFile å°å¯¹è±¡å卿å¡ï¼å¹¶ä¿åæä»¶ä¿¡æ¯å°æ°æ®åº |
| | | * |
| | | * @param file è¦ä¸ä¼ ç MultipartFile 对象 |
| | | * @return ä¸ä¼ æååç SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | */ |
| | | SysOssVo upload(MultipartFile file); |
| | | |
| | | /** |
| | | * ä¸ä¼ æä»¶å°å¯¹è±¡å卿å¡ï¼å¹¶ä¿åæä»¶ä¿¡æ¯å°æ°æ®åº |
| | | * |
| | | * @param file è¦ä¸ä¼ çæä»¶å¯¹è±¡ |
| | | * @return ä¸ä¼ æååç SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | */ |
| | | SysOssVo upload(File file); |
| | | |
| | | /** |
| | | * æä»¶ä¸è½½æ¹æ³ï¼æ¯æä¸æ¬¡æ§ä¸è½½å®æ´æä»¶ |
| | | * |
| | | * @param ossId OSS对象ID |
| | | * @param response HttpServletResponse对象ï¼ç¨äºè®¾ç½®ååºå¤´åå客æ·ç«¯åéæä»¶å
容 |
| | | */ |
| | | void download(Long ossId, HttpServletResponse response) throws IOException; |
| | | |
| | | /** |
| | | * å é¤OSS对象åå¨ |
| | | * |
| | | * @param ids OSS对象ID串 |
| | | * @param isValid 夿æ¯å¦éè¦æ ¡éª |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | | } |
| | |
| | | List<Long> selectPostListByUserId(Long userId); |
| | | |
| | | /** |
| | | * éè¿å²ä½ID串æ¥è¯¢å²ä½ |
| | | * |
| | | * @param postIds å²ä½id串 |
| | | * @return å²ä½åè¡¨ä¿¡æ¯ |
| | | */ |
| | | List<SysPostVo> selectPostByIds(List<Long> postIds); |
| | | |
| | | /** |
| | | * æ ¡éªå²ä½åç§° |
| | | * |
| | | * @param post å²ä½ä¿¡æ¯ |
| | |
| | | List<SysRoleVo> selectRolesByUserId(Long userId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢è§è²å表(å
å«è¢«ææç¶æ) |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return è§è²å表 |
| | | */ |
| | | List<SysRoleVo> selectRolesAuthByUserId(Long userId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢è§è²æé |
| | | * |
| | | * @param userId ç¨æ·ID |
| | |
| | | * @return è§è²å¯¹è±¡ä¿¡æ¯ |
| | | */ |
| | | SysRoleVo selectRoleById(Long roleId); |
| | | |
| | | /** |
| | | * éè¿è§è²ID串æ¥è¯¢è§è² |
| | | * |
| | | * @param roleIds è§è²ID串 |
| | | * @return è§è²åè¡¨ä¿¡æ¯ |
| | | */ |
| | | List<SysRoleVo> selectRoleByIds(List<Long> roleIds); |
| | | |
| | | /** |
| | | * æ ¡éªè§è²åç§°æ¯å¦å¯ä¸ |
| | |
| | | int insertAuthUsers(Long roleId, Long[] userIds); |
| | | |
| | | void cleanOnlineUserByRole(Long roleId); |
| | | |
| | | } |
| | |
| | | /** |
| | | * æ¥è¯¢ç¤¾ä¼åå
³ç³»å表 |
| | | */ |
| | | List<SysSocialVo> queryList(); |
| | | List<SysSocialVo> queryList(SysSocialBo bo); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¤¾ä¼åå
³ç³»å表 |
| | |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ® authId æ¥è¯¢ SysSocial 表å SysUser 表ï¼è¿å SysSocialAuthResult æ å°ç对象 |
| | | * @param authId 认è¯ID |
| | | * @return SysSocial |
| | | * æ ¹æ® authId æ¥è¯¢ |
| | | */ |
| | | List<SysSocialVo> selectByAuthId(String authId); |
| | | |
| | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.system.domain.bo.SysUserBo; |
| | | import org.dromara.system.domain.vo.SysUserExportVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | |
| | | import java.util.List; |
| | |
| | | * @param user ç¨æ·ä¿¡æ¯ |
| | | * @return ç¨æ·ä¿¡æ¯éåä¿¡æ¯ |
| | | */ |
| | | List<SysUserVo> selectUserList(SysUserBo user); |
| | | List<SysUserExportVo> selectUserExportList(SysUserBo user); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¡ä»¶å页æ¥è¯¢å·²åé
ç¨æ·è§è²å表 |
| | |
| | | SysUserVo selectUserById(Long userId); |
| | | |
| | | /** |
| | | * éè¿ç¨æ·ID串æ¥è¯¢ç¨æ· |
| | | * |
| | | * @param userIds ç¨æ·ID串 |
| | | * @param deptId é¨é¨id |
| | | * @return ç¨æ·åè¡¨ä¿¡æ¯ |
| | | */ |
| | | List<SysUserVo> selectUserByIds(List<Long> userIds, Long deptId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢ç¨æ·æå±è§è²ç» |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | String selectUserRoleGroup(String userName); |
| | | String selectUserRoleGroup(Long userId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢ç¨æ·æå±å²ä½ç» |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | String selectUserPostGroup(String userName); |
| | | String selectUserPostGroup(Long userId); |
| | | |
| | | /** |
| | | * æ ¡éªç¨æ·åç§°æ¯å¦å¯ä¸ |
| | |
| | | /** |
| | | * éè¿é¨é¨idæ¥è¯¢å½åé¨é¨ææç¨æ· |
| | | * |
| | | * @param deptId |
| | | * @return |
| | | * @param deptId é¨é¨id |
| | | * @return ç»æ |
| | | */ |
| | | List<SysUserVo> selectUserListByDept(Long deptId); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.mapper.SysClientMapper; |
| | | import org.dromara.system.service.ISysClientService; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | |
| | | /** |
| | | * æ¥è¯¢å®¢æ·ç«¯ç®¡ç |
| | | */ |
| | | @Cacheable(cacheNames = CacheNames.SYS_CLIENT, key = "#clientId") |
| | | @Override |
| | | public SysClient queryByClientId(String clientId) { |
| | | return baseMapper.selectOne(new LambdaQueryWrapper<SysClient>().eq(SysClient::getClientId, clientId)); |
| | | public SysClientVo queryByClientId(String clientId) { |
| | | return baseMapper.selectVoOne(new LambdaQueryWrapper<SysClient>().eq(SysClient::getClientId, clientId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * ä¿®æ¹å®¢æ·ç«¯ç®¡ç |
| | | */ |
| | | @CacheEvict(cacheNames = CacheNames.SYS_CLIENT, key = "#bo.clientId") |
| | | @Override |
| | | public Boolean updateByBo(SysClientBo bo) { |
| | | SysClient update = MapstructUtils.convert(bo, SysClient.class); |
| | |
| | | /** |
| | | * ä¿®æ¹ç¶æ |
| | | */ |
| | | @CacheEvict(cacheNames = CacheNames.SYS_CLIENT, key = "#clientId") |
| | | @Override |
| | | public int updateUserStatus(Long id, String status) { |
| | | public int updateUserStatus(String clientId, String status) { |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysClient>() |
| | | .set(SysClient::getStatus, status) |
| | | .eq(SysClient::getId, id)); |
| | | .eq(SysClient::getClientId, clientId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * æ¹éå é¤å®¢æ·ç«¯ç®¡ç |
| | | */ |
| | | @CacheEvict(cacheNames = CacheNames.SYS_CLIENT, allEntries = true) |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if (isValid) { |
| | |
| | | } |
| | | row = baseMapper.updateById(config); |
| | | } else { |
| | | CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey()); |
| | | row = baseMapper.update(config, new LambdaQueryWrapper<SysConfig>() |
| | | .eq(SysConfig::getConfigKey, config.getConfigKey())); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | |
| | | import org.dromara.system.mapper.SysRoleMapper; |
| | | import org.dromara.system.mapper.SysUserMapper; |
| | | import org.dromara.system.service.ISysDeptService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId()); |
| | | lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getDeptCategory()), SysDept::getDeptCategory, bo.getDeptCategory()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus()); |
| | | lqw.orderByAsc(SysDept::getAncestors); |
| | | lqw.orderByAsc(SysDept::getParentId); |
| | | lqw.orderByAsc(SysDept::getOrderNum); |
| | | lqw.orderByAsc(SysDept::getDeptId); |
| | |
| | | .select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId())); |
| | | dept.setParentName(ObjectUtil.isNotNull(parentDept) ? parentDept.getDeptName() : null); |
| | | return dept; |
| | | } |
| | | |
| | | @Override |
| | | public List<SysDeptVo> selectDeptByIds(List<Long> deptIds) { |
| | | return baseMapper.selectDeptList(new LambdaQueryWrapper<SysDept>() |
| | | .select(SysDept::getDeptId, SysDept::getDeptName, SysDept::getLeader) |
| | | .eq(SysDept::getStatus, UserConstants.DEPT_NORMAL) |
| | | .in(CollUtil.isNotEmpty(deptIds), SysDept::getDeptId, deptIds)); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªé¨é¨ç±»å«ç¼ç æ¯å¦å¯ä¸ |
| | | * |
| | | * @param dept é¨é¨ä¿¡æ¯ |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public boolean checkDeptCategoryUnique(SysDeptBo dept) { |
| | | boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDept>() |
| | | .eq(SysDept::getDeptCategory, dept.getDeptCategory()) |
| | | .ne(ObjectUtil.isNotNull(dept.getDeptId()), SysDept::getDeptId, dept.getDeptId())); |
| | | return !exist; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªé¨é¨æ¯å¦ææ°æ®æé |
| | | * |
| | | * @param deptId é¨é¨id |
| | |
| | | if (LoginHelper.isSuperAdmin()) { |
| | | return; |
| | | } |
| | | SysDeptVo dept = baseMapper.selectDeptById(deptId); |
| | | if (ObjectUtil.isNull(dept)) { |
| | | if (baseMapper.countDeptById(deptId) == 0) { |
| | | throw new ServiceException("没ææé访é®é¨é¨æ°æ®ï¼"); |
| | | } |
| | | } |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | throw new ServiceException("æä½å¤±è´¥"); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªåå
¸é®å¼æ¯å¦å¯ä¸ |
| | | * |
| | | * @param dict åå
¸æ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public boolean checkDictDataUnique(SysDictDataBo dict) { |
| | | Long dictCode = ObjectUtil.isNull(dict.getDictCode()) ? -1L : dict.getDictCode(); |
| | | SysDictData entity = baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>() |
| | | .eq(SysDictData::getDictType, dict.getDictType()).eq(SysDictData::getDictValue, dict.getDictValue())); |
| | | if (ObjectUtil.isNotNull(entity) && !dictCode.equals(entity.getDictCode())) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | } |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.dev33.satoken.context.SaHolder; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | 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.dromara.common.core.constant.CacheConstants; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.service.DictService; |
| | |
| | | import org.dromara.system.mapper.SysDictDataMapper; |
| | | import org.dromara.system.mapper.SysDictTypeMapper; |
| | | import org.dromara.system.service.ISysDictTypeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.cache.annotation.CachePut; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | * @param separator åé符 |
| | | * @return åå
¸æ ç¾ |
| | | */ |
| | | @SuppressWarnings("unchecked cast") |
| | | @Override |
| | | public String getDictLabel(String dictType, String dictValue, String separator) { |
| | | // ä¼å
仿¬å°ç¼åè·å |
| | | List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); |
| | | if (ObjectUtil.isNull(datas)) { |
| | | datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); |
| | | SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); |
| | | } |
| | | |
| | | List<SysDictDataVo> datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); |
| | | Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel); |
| | | if (StringUtils.containsAny(dictValue, separator)) { |
| | | return Arrays.stream(dictValue.split(separator)) |
| | |
| | | * @param separator åé符 |
| | | * @return åå
¸å¼ |
| | | */ |
| | | @SuppressWarnings("unchecked cast") |
| | | @Override |
| | | public String getDictValue(String dictType, String dictLabel, String separator) { |
| | | // ä¼å
仿¬å°ç¼åè·å |
| | | List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); |
| | | if (ObjectUtil.isNull(datas)) { |
| | | datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); |
| | | SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); |
| | | } |
| | | |
| | | List<SysDictDataVo> datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); |
| | | Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictLabel, SysDictDataVo::getDictValue); |
| | | if (StringUtils.containsAny(dictLabel, separator)) { |
| | | return Arrays.stream(dictLabel.split(separator)) |
| | |
| | | import cn.hutool.http.useragent.UserAgentUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.log.event.LogininforEvent; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.core.utils.ServletUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.core.utils.ip.AddressUtils; |
| | | import org.dromara.common.log.event.LogininforEvent; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysLogininfor; |
| | | import org.dromara.system.domain.bo.SysLogininforBo; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysLogininforVo; |
| | | import org.dromara.system.mapper.SysClientMapper; |
| | | import org.dromara.system.mapper.SysLogininforMapper; |
| | | import org.dromara.system.service.ISysClientService; |
| | | import org.dromara.system.service.ISysLogininforService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | |
| | | final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent")); |
| | | final String ip = ServletUtils.getClientIP(request); |
| | | // 客æ·ç«¯ä¿¡æ¯ |
| | | String clientid = request.getHeader(LoginHelper.CLIENT_KEY); |
| | | SysClient client = null; |
| | | if (StringUtils.isNotBlank(clientid)) { |
| | | client = clientService.queryByClientId(clientid); |
| | | String clientId = request.getHeader(LoginHelper.CLIENT_KEY); |
| | | SysClientVo client = null; |
| | | if (StringUtils.isNotBlank(clientId)) { |
| | | client = clientService.queryByClientId(clientId); |
| | | } |
| | | |
| | | String address = AddressUtils.getRealAddressByIP(ip); |
| | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.system.domain.SysNotice; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.bo.SysNoticeBo; |
| | | import org.dromara.system.domain.vo.SysNoticeVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | |
| | | lqw.like(StringUtils.isNotBlank(bo.getNoticeTitle()), SysNotice::getNoticeTitle, bo.getNoticeTitle()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getNoticeType()), SysNotice::getNoticeType, bo.getNoticeType()); |
| | | if (StringUtils.isNotBlank(bo.getCreateByName())) { |
| | | SysUserVo sysUser = userMapper.selectUserByUserName(bo.getCreateByName()); |
| | | SysUserVo sysUser = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, bo.getCreateByName())); |
| | | lqw.eq(SysNotice::getCreateBy, ObjectUtil.isNotNull(sysUser) ? sysUser.getUserId() : null); |
| | | } |
| | | lqw.orderByAsc(SysNotice::getNoticeId); |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | 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.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.domain.dto.OssDTO; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.service.OssService; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | |
| | | import org.dromara.system.domain.vo.SysOssVo; |
| | | import org.dromara.system.mapper.SysOssMapper; |
| | | import org.dromara.system.service.ISysOssService; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.http.MediaType; |
| | |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.*; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ æå¡å±å®ç° |
| | |
| | | |
| | | private final SysOssMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢OSS对象åå¨å表 |
| | | * |
| | | * @param bo OSS对象åå¨å页æ¥è¯¢å¯¹è±¡ |
| | | * @param pageQuery å页æ¥è¯¢å®ä½ç±» |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo); |
| | |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ä¸ç» ossIds è·å对åºç SysOssVo å表 |
| | | * |
| | | * @param ossIds ä¸ç»æä»¶å¨æ°æ®åºä¸çå¯ä¸æ è¯éå |
| | | * @return å
å« SysOssVo 对象çå表 |
| | | */ |
| | | @Override |
| | | public List<SysOssVo> listByIds(Collection<Long> ossIds) { |
| | | List<SysOssVo> list = new ArrayList<>(); |
| | |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ä¸ç» ossIds è·åå¯¹åºæä»¶ç URL å表 |
| | | * |
| | | * @param ossIds 以éå·åéç ossId å符串 |
| | | * @return 以éå·åéçæä»¶ URL å符串 |
| | | */ |
| | | @Override |
| | | public String selectUrlByIds(String ossIds) { |
| | | List<String> list = new ArrayList<>(); |
| | |
| | | return String.join(StringUtils.SEPARATOR, list); |
| | | } |
| | | |
| | | @Override |
| | | public List<OssDTO> selectByIds(String ossIds) { |
| | | List<OssDTO> list = new ArrayList<>(); |
| | | for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) { |
| | | SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); |
| | | if (ObjectUtil.isNotNull(vo)) { |
| | | try { |
| | | vo.setUrl(this.matchingUrl(vo).getUrl()); |
| | | list.add(BeanUtil.toBean(vo, OssDTO.class)); |
| | | } catch (Exception ignored) { |
| | | // 妿osså¼å¸¸æ æ³è¿æ¥åå°æ°æ®ç´æ¥è¿å |
| | | list.add(BeanUtil.toBean(vo, OssDTO.class)); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery(); |
| | |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ® ossId ä»ç¼åææ°æ®åºä¸è·å SysOssVo 对象 |
| | | * |
| | | * @param ossId æä»¶å¨æ°æ®åºä¸çå¯ä¸æ è¯ |
| | | * @return SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | */ |
| | | @Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId") |
| | | @Override |
| | | public SysOssVo getById(Long ossId) { |
| | | return baseMapper.selectVoById(ossId); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æä»¶ä¸è½½æ¹æ³ï¼æ¯æä¸æ¬¡æ§ä¸è½½å®æ´æä»¶ |
| | | * |
| | | * @param ossId OSS对象ID |
| | | * @param response HttpServletResponse对象ï¼ç¨äºè®¾ç½®ååºå¤´åå客æ·ç«¯åéæä»¶å
容 |
| | | */ |
| | | @Override |
| | | public void download(Long ossId, HttpServletResponse response) throws IOException { |
| | | SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); |
| | |
| | | FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName()); |
| | | response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); |
| | | OssClient storage = OssFactory.instance(sysOss.getService()); |
| | | try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { |
| | | int available = inputStream.available(); |
| | | IoUtil.copy(inputStream, response.getOutputStream(), available); |
| | | response.setContentLength(available); |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | long contentLength = storage.download(sysOss.getFileName(), response.getOutputStream()); |
| | | response.setContentLengthLong(contentLength); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ MultipartFile å°å¯¹è±¡å卿å¡ï¼å¹¶ä¿åæä»¶ä¿¡æ¯å°æ°æ®åº |
| | | * |
| | | * @param file è¦ä¸ä¼ ç MultipartFile 对象 |
| | | * @return ä¸ä¼ æååç SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | * @throws ServiceException 妿ä¸ä¼ è¿ç¨ä¸åçå¼å¸¸ï¼åæåº ServiceException å¼å¸¸ |
| | | */ |
| | | @Override |
| | | public SysOssVo upload(MultipartFile file) { |
| | | String originalfileName = file.getOriginalFilename(); |
| | |
| | | OssClient storage = OssFactory.instance(); |
| | | UploadResult uploadResult; |
| | | try { |
| | | uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); |
| | | uploadResult = storage.uploadSuffix(file.getBytes(), suffix); |
| | | } catch (IOException e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | |
| | | return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ æä»¶å°å¯¹è±¡å卿å¡ï¼å¹¶ä¿åæä»¶ä¿¡æ¯å°æ°æ®åº |
| | | * |
| | | * @param file è¦ä¸ä¼ çæä»¶å¯¹è±¡ |
| | | * @return ä¸ä¼ æååç SysOssVo 对象ï¼å
å«æä»¶ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public SysOssVo upload(File file) { |
| | | String originalfileName = file.getName(); |
| | |
| | | return this.matchingUrl(sysOssVo); |
| | | } |
| | | |
| | | /** |
| | | * å é¤OSS对象åå¨ |
| | | * |
| | | * @param ids OSS对象ID串 |
| | | * @param isValid 夿æ¯å¦éè¦æ ¡éª |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if (isValid) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * å¹é
Url |
| | | * æ¡¶ç±»å为 private çURL ä¿®æ¹ä¸ºä¸´æ¶URLæ¶é¿ä¸º120s |
| | | * |
| | | * @param oss OSS对象 |
| | | * @return oss å¹é
UrlçOSS对象 |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | 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 com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.helper.DataBaseHelper; |
| | | import org.dromara.system.domain.SysDept; |
| | | import org.dromara.system.domain.SysPost; |
| | | import org.dromara.system.domain.SysUserPost; |
| | | import org.dromara.system.domain.bo.SysPostBo; |
| | | import org.dromara.system.domain.vo.SysPostVo; |
| | | import org.dromara.system.mapper.SysDeptMapper; |
| | | import org.dromara.system.mapper.SysPostMapper; |
| | | import org.dromara.system.mapper.SysUserPostMapper; |
| | | import org.dromara.system.service.ISysPostService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * å²ä½ä¿¡æ¯ æå¡å±å¤ç |
| | |
| | | public class SysPostServiceImpl implements ISysPostService { |
| | | |
| | | private final SysPostMapper baseMapper; |
| | | private final SysDeptMapper deptMapper; |
| | | private final SysUserPostMapper userPostMapper; |
| | | |
| | | @Override |
| | | public TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post); |
| | | Page<SysPostVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | Page<SysPostVo> page = baseMapper.selectPagePostList(pageQuery.build(), buildQueryWrapper(post)); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public List<SysPostVo> selectPostList(SysPostBo post) { |
| | | LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post); |
| | | return baseMapper.selectVoList(lqw); |
| | | return baseMapper.selectVoList(buildQueryWrapper(post)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ¥è¯¢æ¡ä»¶æå»ºæ¥è¯¢å
è£
å¨ |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶å¯¹è±¡ |
| | | * @return æå»ºå¥½çæ¥è¯¢å
è£
å¨ |
| | | */ |
| | | private LambdaQueryWrapper<SysPost> buildQueryWrapper(SysPostBo bo) { |
| | | LambdaQueryWrapper<SysPost> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getPostCode()), SysPost::getPostCode, bo.getPostCode()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getPostName()), SysPost::getPostName, bo.getPostName()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysPost::getStatus, bo.getStatus()); |
| | | lqw.orderByAsc(SysPost::getPostSort); |
| | | return lqw; |
| | | LambdaQueryWrapper<SysPost> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.like(StringUtils.isNotBlank(bo.getPostCode()), SysPost::getPostCode, bo.getPostCode()) |
| | | .like(StringUtils.isNotBlank(bo.getPostCategory()), SysPost::getPostCategory, bo.getPostCategory()) |
| | | .like(StringUtils.isNotBlank(bo.getPostName()), SysPost::getPostName, bo.getPostName()) |
| | | .eq(StringUtils.isNotBlank(bo.getStatus()), SysPost::getStatus, bo.getStatus()) |
| | | .orderByAsc(SysPost::getPostSort); |
| | | if (ObjectUtil.isNotNull(bo.getDeptId())) { |
| | | //ä¼å
åé¨é¨æç´¢ |
| | | wrapper.eq(SysPost::getDeptId, bo.getDeptId()); |
| | | } else if (ObjectUtil.isNotNull(bo.getBelongDeptId())) { |
| | | //é¨é¨æ æç´¢ |
| | | wrapper.and(x -> { |
| | | List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>() |
| | | .select(SysDept::getDeptId) |
| | | .apply(DataBaseHelper.findInSet(bo.getBelongDeptId(), "ancestors"))) |
| | | .stream() |
| | | .map(SysDept::getDeptId) |
| | | .collect(Collectors.toList()); |
| | | deptIds.add(bo.getBelongDeptId()); |
| | | x.in(SysPost::getDeptId, deptIds); |
| | | }); |
| | | } |
| | | return wrapper; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public List<Long> selectPostListByUserId(Long userId) { |
| | | return baseMapper.selectPostListByUserId(userId); |
| | | List<SysPostVo> list = baseMapper.selectPostsByUserId(userId); |
| | | return StreamUtils.toList(list, SysPostVo::getPostId); |
| | | } |
| | | |
| | | /** |
| | | * éè¿å²ä½ID串æ¥è¯¢å²ä½ |
| | | * |
| | | * @param postIds å²ä½id串 |
| | | * @return å²ä½åè¡¨ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public List<SysPostVo> selectPostByIds(List<Long> postIds) { |
| | | return baseMapper.selectVoList(new LambdaQueryWrapper<SysPost>() |
| | | .select(SysPost::getPostId, SysPost::getPostName, SysPost::getPostCode) |
| | | .eq(SysPost::getStatus, UserConstants.POST_NORMAL) |
| | | .in(CollUtil.isNotEmpty(postIds), SysPost::getPostId, postIds)); |
| | | } |
| | | |
| | | /** |
| | |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "r.create_time", params.get("beginTime"), params.get("endTime")) |
| | | .orderByAsc("r.role_sort").orderByAsc("r.create_time"); |
| | | ; |
| | | return wrapper; |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRolesByUserId(Long userId) { |
| | | return baseMapper.selectRolesByUserId(userId); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢è§è²å表(å
å«è¢«ææç¶æ) |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return è§è²å表 |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRolesAuthByUserId(Long userId) { |
| | | List<SysRoleVo> userRoles = baseMapper.selectRolePermissionByUserId(userId); |
| | | List<SysRoleVo> roles = selectRoleAll(); |
| | | for (SysRoleVo role : roles) { |
| | |
| | | */ |
| | | @Override |
| | | public List<Long> selectRoleListByUserId(Long userId) { |
| | | return baseMapper.selectRoleListByUserId(userId); |
| | | List<SysRoleVo> list = baseMapper.selectRolesByUserId(userId); |
| | | return StreamUtils.toList(list, SysRoleVo::getRoleId); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * éè¿è§è²ID串æ¥è¯¢è§è² |
| | | * |
| | | * @param roleIds è§è²ID串 |
| | | * @return è§è²åè¡¨ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRoleByIds(List<Long> roleIds) { |
| | | return baseMapper.selectRoleList(new QueryWrapper<SysRole>() |
| | | .eq("r.status", UserConstants.ROLE_NORMAL) |
| | | .in(CollUtil.isNotEmpty(roleIds), "r.role_id", roleIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªè§è²åç§°æ¯å¦å¯ä¸ |
| | | * |
| | | * @param role è§è²ä¿¡æ¯ |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.system.domain.SysSocial; |
| | | import org.dromara.system.domain.bo.SysSocialBo; |
| | | import org.dromara.system.domain.vo.SysSocialVo; |
| | |
| | | * ææå表 |
| | | */ |
| | | @Override |
| | | public List<SysSocialVo> queryList() { |
| | | return baseMapper.selectVoList(); |
| | | public List<SysSocialVo> queryList(SysSocialBo bo) { |
| | | LambdaQueryWrapper<SysSocial> lqw = new LambdaQueryWrapper<SysSocial>() |
| | | .eq(ObjectUtil.isNotNull(bo.getUserId()), SysSocial::getUserId, bo.getUserId()) |
| | | .eq(StringUtils.isNotBlank(bo.getAuthId()), SysSocial::getAuthId, bo.getAuthId()) |
| | | .eq(StringUtils.isNotBlank(bo.getSource()), SysSocial::getSource, bo.getSource()); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | @Override |
| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.constant.CacheNames; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.domain.dto.UserDTO; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.service.UserService; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | |
| | | import org.dromara.system.domain.bo.SysUserBo; |
| | | import org.dromara.system.domain.vo.SysPostVo; |
| | | import org.dromara.system.domain.vo.SysRoleVo; |
| | | import org.dromara.system.domain.vo.SysUserExportVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | | import org.dromara.system.mapper.*; |
| | | import org.dromara.system.service.ISysUserService; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | |
| | | * @return ç¨æ·ä¿¡æ¯éåä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public List<SysUserVo> selectUserList(SysUserBo user) { |
| | | return baseMapper.selectUserList(this.buildQueryWrapper(user)); |
| | | public List<SysUserExportVo> selectUserExportList(SysUserBo user) { |
| | | return baseMapper.selectUserExportList(this.buildQueryWrapper(user)); |
| | | } |
| | | |
| | | private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) { |
| | | Map<String, Object> params = user.getParams(); |
| | | QueryWrapper<SysUser> wrapper = Wrappers.query(); |
| | | wrapper.eq("u.del_flag", UserConstants.USER_NORMAL) |
| | | .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId()) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "u.create_time", params.get("beginTime"), params.get("endTime")) |
| | | .and(ObjectUtil.isNotNull(user.getDeptId()), w -> { |
| | | List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>() |
| | | .select(SysDept::getDeptId) |
| | | .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors"))); |
| | | List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId); |
| | | ids.add(user.getDeptId()); |
| | | w.in("u.dept_id", ids); |
| | | }).orderByAsc("u.user_id"); |
| | | .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId()) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "u.create_time", params.get("beginTime"), params.get("endTime")) |
| | | .and(ObjectUtil.isNotNull(user.getDeptId()), w -> { |
| | | List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>() |
| | | .select(SysDept::getDeptId) |
| | | .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors"))); |
| | | List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId); |
| | | ids.add(user.getDeptId()); |
| | | w.in("u.dept_id", ids); |
| | | }).orderByAsc("u.user_id"); |
| | | if (StringUtils.isNotBlank(user.getExcludeUserIds())) { |
| | | wrapper.notIn("u.user_id", StringUtils.splitList(user.getExcludeUserIds())); |
| | | } |
| | | return wrapper; |
| | | } |
| | | |
| | |
| | | public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery) { |
| | | QueryWrapper<SysUser> wrapper = Wrappers.query(); |
| | | wrapper.eq("u.del_flag", UserConstants.USER_NORMAL) |
| | | .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId()) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .orderByAsc("u.user_id"); |
| | | .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId()) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .orderByAsc("u.user_id"); |
| | | Page<SysUserVo> page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | |
| | | List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId()); |
| | | QueryWrapper<SysUser> wrapper = Wrappers.query(); |
| | | wrapper.eq("u.del_flag", UserConstants.USER_NORMAL) |
| | | .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id")) |
| | | .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .orderByAsc("u.user_id"); |
| | | .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id")) |
| | | .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) |
| | | .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) |
| | | .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) |
| | | .orderByAsc("u.user_id"); |
| | | Page<SysUserVo> page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public SysUserVo selectUserByUserName(String userName) { |
| | | return baseMapper.selectUserByUserName(userName); |
| | | return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public SysUserVo selectUserByPhonenumber(String phonenumber) { |
| | | return baseMapper.selectUserByPhonenumber(phonenumber); |
| | | return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public SysUserVo selectUserById(Long userId) { |
| | | return baseMapper.selectUserById(userId); |
| | | SysUserVo user = baseMapper.selectVoById(userId); |
| | | if (ObjectUtil.isNull(user)) { |
| | | return user; |
| | | } |
| | | user.setRoles(roleMapper.selectRolesByUserId(user.getUserId())); |
| | | return user; |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·ID串æ¥è¯¢ç¨æ· |
| | | * |
| | | * @param userIds ç¨æ·ID串 |
| | | * @param deptId é¨é¨id |
| | | * @return ç¨æ·åè¡¨ä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public List<SysUserVo> selectUserByIds(List<Long> userIds, Long deptId) { |
| | | return baseMapper.selectUserList(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName) |
| | | .eq(SysUser::getStatus, UserConstants.USER_NORMAL) |
| | | .eq(ObjectUtil.isNotNull(deptId), SysUser::getDeptId, deptId) |
| | | .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¨æ·æå±è§è²ç» |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public String selectUserRoleGroup(String userName) { |
| | | List<SysRoleVo> list = roleMapper.selectRolesByUserName(userName); |
| | | public String selectUserRoleGroup(Long userId) { |
| | | List<SysRoleVo> list = roleMapper.selectRolesByUserId(userId); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | |
| | | /** |
| | | * æ¥è¯¢ç¨æ·æå±å²ä½ç» |
| | | * |
| | | * @param userName ç¨æ·å |
| | | * @param userId ç¨æ·ID |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public String selectUserPostGroup(String userName) { |
| | | List<SysPostVo> list = postMapper.selectPostsByUserName(userName); |
| | | public String selectUserPostGroup(Long userId) { |
| | | List<SysPostVo> list = postMapper.selectPostsByUserId(userId); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return StringUtils.EMPTY; |
| | | } |
| | |
| | | @Override |
| | | public boolean checkUserNameUnique(SysUserBo user) { |
| | | boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>() |
| | | .eq(SysUser::getUserName, user.getUserName()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | .eq(SysUser::getUserName, user.getUserName()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | return !exist; |
| | | } |
| | | |
| | |
| | | @Override |
| | | public boolean checkPhoneUnique(SysUserBo user) { |
| | | boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>() |
| | | .eq(SysUser::getPhonenumber, user.getPhonenumber()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | .eq(SysUser::getPhonenumber, user.getPhonenumber()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | return !exist; |
| | | } |
| | | |
| | |
| | | @Override |
| | | public boolean checkEmailUnique(SysUserBo user) { |
| | | boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>() |
| | | .eq(SysUser::getEmail, user.getEmail()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | .eq(SysUser::getEmail, user.getEmail()) |
| | | .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); |
| | | return !exist; |
| | | } |
| | | |
| | |
| | | if (LoginHelper.isSuperAdmin()) { |
| | | return; |
| | | } |
| | | if (ObjectUtil.isNull(baseMapper.selectUserById(userId))) { |
| | | if (baseMapper.countUserById(userId) == 0) { |
| | | throw new ServiceException("没ææé访é®ç¨æ·æ°æ®ï¼"); |
| | | } |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public boolean registerUser(SysUserBo user, String tenantId) { |
| | | user.setCreateBy(user.getUserId()); |
| | | user.setUpdateBy(user.getUserId()); |
| | | user.setCreateBy(0L); |
| | | user.setUpdateBy(0L); |
| | | SysUser sysUser = MapstructUtils.convert(user, SysUser.class); |
| | | sysUser.setTenantId(tenantId); |
| | | return baseMapper.insert(sysUser) > 0; |
| | |
| | | @Override |
| | | public int updateUserStatus(Long userId, String status) { |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getStatus, status) |
| | | .eq(SysUser::getUserId, userId)); |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getStatus, status) |
| | | .eq(SysUser::getUserId, userId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public int updateUserProfile(SysUserBo user) { |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName()) |
| | | .set(SysUser::getPhonenumber, user.getPhonenumber()) |
| | | .set(SysUser::getEmail, user.getEmail()) |
| | | .set(SysUser::getSex, user.getSex()) |
| | | .eq(SysUser::getUserId, user.getUserId())); |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName()) |
| | | .set(SysUser::getPhonenumber, user.getPhonenumber()) |
| | | .set(SysUser::getEmail, user.getEmail()) |
| | | .set(SysUser::getSex, user.getSex()) |
| | | .eq(SysUser::getUserId, user.getUserId())); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public boolean updateUserAvatar(Long userId, Long avatar) { |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getAvatar, avatar) |
| | | .eq(SysUser::getUserId, userId)) > 0; |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getAvatar, avatar) |
| | | .eq(SysUser::getUserId, userId)) > 0; |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public int resetUserPwd(Long userId, String password) { |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getPassword, password) |
| | | .eq(SysUser::getUserId, userId)); |
| | | new LambdaUpdateWrapper<SysUser>() |
| | | .set(SysUser::getPassword, password) |
| | | .eq(SysUser::getUserId, userId)); |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * éè¿é¨é¨idæ¥è¯¢å½åé¨é¨ææç¨æ· |
| | | * |
| | | * @param deptId |
| | | * @return |
| | | * @param deptId é¨é¨ID |
| | | * @return ç¨æ·ä¿¡æ¯éåä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public List<SysUserVo> selectUserListByDept(Long deptId) { |
| | |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·è´¦æ· |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return ç¨æ·è´¦æ· |
| | | */ |
| | | @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId") |
| | | @Override |
| | | public String selectUserNameById(Long userId) { |
| | | SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getUserName).eq(SysUser::getUserId, userId)); |
| | | .select(SysUser::getUserName).eq(SysUser::getUserId, userId)); |
| | | return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName(); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·è´¦æ· |
| | | * |
| | | * @param userId ç¨æ·ID |
| | | * @return ç¨æ·è´¦æ· |
| | | */ |
| | | @Override |
| | | @Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId") |
| | | public String selectNicknameById(Long userId) { |
| | |
| | | .select(SysUser::getNickName).eq(SysUser::getUserId, userId)); |
| | | return ObjectUtil.isNull(sysUser) ? null : sysUser.getNickName(); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·è´¦æ· |
| | | * |
| | | * @param userIds ç¨æ·ID å¤ä¸ªç¨éå·éå¼ |
| | | * @return ç¨æ·è´¦æ· |
| | | */ |
| | | @Override |
| | | public String selectNicknameByIds(String userIds) { |
| | | List<String> list = new ArrayList<>(); |
| | | for (Long id : StringUtils.splitTo(userIds, Convert::toLong)) { |
| | | String nickname = SpringUtils.getAopProxy(this).selectNicknameById(id); |
| | | if (StringUtils.isNotBlank(nickname)) { |
| | | list.add(nickname); |
| | | } |
| | | } |
| | | return String.join(StringUtils.SEPARATOR, list); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·ææºå· |
| | | * |
| | | * @param userId ç¨æ·id |
| | | * @return ç¨æ·ææºå· |
| | | */ |
| | | @Override |
| | | public String selectPhonenumberById(Long userId) { |
| | | SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getPhonenumber).eq(SysUser::getUserId, userId)); |
| | | return ObjectUtil.isNull(sysUser) ? null : sysUser.getPhonenumber(); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¨æ·IDæ¥è¯¢ç¨æ·é®ç®± |
| | | * |
| | | * @param userId ç¨æ·id |
| | | * @return ç¨æ·é®ç®± |
| | | */ |
| | | @Override |
| | | public String selectEmailById(Long userId) { |
| | | SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>() |
| | | .select(SysUser::getEmail).eq(SysUser::getUserId, userId)); |
| | | return ObjectUtil.isNull(sysUser) ? null : sysUser.getEmail(); |
| | | } |
| | | |
| | | @Override |
| | | public List<UserDTO> selectListByIds(List<Long> userIds) { |
| | | if (CollUtil.isEmpty(userIds)) { |
| | | return List.of(); |
| | | } |
| | | List<SysUserVo> list = this.selectUserByIds(userIds, null); |
| | | return BeanUtil.copyToList(list, UserDTO.class); |
| | | } |
| | | |
| | | @Override |
| | | public List<Long> selectUserIdsByRoleIds(List<Long> roleIds) { |
| | | List<SysUserRole> userRoles = userRoleMapper.selectList( |
| | | new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, roleIds)); |
| | | return StreamUtils.toList(userRoles, SysUserRole::getUserId); |
| | | } |
| | | |
| | | } |
| | |
| | | </resultMap> |
| | | |
| | | <select id="selectDeptList" resultMap="SysDeptResult"> |
| | | select * from sys_dept ${ew.getCustomSqlSegment} |
| | | select |
| | | <if test="ew.getSqlSelect != null"> |
| | | ${ew.getSqlSelect} |
| | | </if> |
| | | <if test="ew.getSqlSelect == null"> |
| | | * |
| | | </if> |
| | | from sys_dept ${ew.getCustomSqlSegment} |
| | | </select> |
| | | |
| | | <select id="selectDeptById" resultMap="SysDeptResult"> |
| | | select * from sys_dept where del_flag = '0' and dept_id = #{deptId} |
| | | <select id="countDeptById" resultType="Long"> |
| | | select count(*) from sys_dept where del_flag = '0' and dept_id = #{deptId} |
| | | </select> |
| | | |
| | | <select id="selectDeptListByRoleId" resultType="Long"> |
| | |
| | | <resultMap type="org.dromara.system.domain.vo.SysPostVo" id="SysPostResult"> |
| | | </resultMap> |
| | | |
| | | <select id="selectPostListByUserId" parameterType="Long" resultType="Long"> |
| | | select p.post_id |
| | | <select id="selectPagePostList" resultMap="SysPostResult"> |
| | | select |
| | | <if test="ew.getSqlSelect != null"> |
| | | ${ew.getSqlSelect} |
| | | </if> |
| | | <if test="ew.getSqlSelect == null"> |
| | | * |
| | | </if> |
| | | from sys_post ${ew.getCustomSqlSegment} |
| | | </select> |
| | | |
| | | <select id="selectPostsByUserId" parameterType="Long" resultMap="SysPostResult"> |
| | | select p.post_id, p.dept_id, p.post_name, p.post_code, p.post_category |
| | | from sys_post p |
| | | left join sys_user_post up on up.post_id = p.post_id |
| | | left join sys_user u on u.user_id = up.user_id |
| | | where u.user_id = #{userId} |
| | | </select> |
| | | |
| | | <select id="selectPostsByUserName" parameterType="String" resultMap="SysPostResult"> |
| | | select p.post_id, p.post_name, p.post_code |
| | | from sys_post p |
| | | left join sys_user_post up on up.post_id = p.post_id |
| | | left join sys_user u on u.user_id = up.user_id |
| | | where u.user_name = #{userName} |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | WHERE r.del_flag = '0' and sur.user_id = #{userId} |
| | | </select> |
| | | |
| | | <select id="selectRoleListByUserId" parameterType="Long" resultType="Long"> |
| | | select r.role_id |
| | | from sys_role r |
| | | left join sys_user_role sur on sur.role_id = r.role_id |
| | | left join sys_user u on u.user_id = sur.user_id |
| | | where u.user_id = #{userId} |
| | | </select> |
| | | |
| | | <select id="selectRolesByUserName" parameterType="String" resultMap="SysRoleResult"> |
| | | <select id="selectRolesByUserId" parameterType="Long" resultMap="SysRoleResult"> |
| | | select r.role_id, |
| | | r.role_name, |
| | | r.role_key, |
| | | r.role_sort |
| | | r.role_sort, |
| | | r.data_scope, |
| | | r.status |
| | | from sys_role r |
| | | left join sys_user_role sur on sur.role_id = r.role_id |
| | | left join sys_user u on u.user_id = sur.user_id |
| | | WHERE r.del_flag = '0' and u.user_name = #{userName} |
| | | WHERE r.del_flag = '0' and sur.user_id = #{userId} |
| | | </select> |
| | | |
| | | <select id="selectRoleById" resultMap="SysRoleResult"> |
| | |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="org.dromara.system.mapper.SysUserMapper"> |
| | | |
| | | <!-- å¤ç»æåµå¥èªå¨æ å°é另䏿¯ä¸ªå®ä½ç主é®id å¦åæ å°ä¼å¤±è´¥ --> |
| | | <resultMap type="org.dromara.system.domain.vo.SysUserVo" id="SysUserResult"> |
| | | <id property="userId" column="user_id"/> |
| | | <result property="deptId" column="dept_id"/> |
| | | <association property="dept" column="dept_id" resultMap="deptResult"/> |
| | | <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="deptResult" type="org.dromara.system.domain.vo.SysDeptVo"> |
| | | <id property="deptId" column="dept_id"/> |
| | | <result property="email" column="dept_email"/> |
| | | <result property="status" column="dept_status"/> |
| | | <result property="createTime" column="dept_create_time"/> |
| | | <resultMap type="org.dromara.system.domain.vo.SysUserExportVo" id="SysUserExportResult"> |
| | | <id property="userId" column="user_id"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="RoleResult" type="org.dromara.system.domain.vo.SysRoleVo"> |
| | | <id property="roleId" column="role_id"/> |
| | | <result property="status" column="role_status"/> |
| | | <result property="createTime" column="role_create_time"/> |
| | | </resultMap> |
| | | |
| | | <sql id="selectUserVo"> |
| | | select u.user_id, |
| | | u.tenant_id, |
| | | u.dept_id, |
| | | u.user_name, |
| | | u.nick_name, |
| | | u.user_type, |
| | | u.email, |
| | | u.avatar, |
| | | u.phonenumber, |
| | | u.password, |
| | | u.sex, |
| | | u.status, |
| | | u.del_flag, |
| | | u.login_ip, |
| | | u.login_date, |
| | | u.create_by, |
| | | u.create_time, |
| | | u.remark, |
| | | d.dept_id, |
| | | d.parent_id, |
| | | d.ancestors, |
| | | d.dept_name, |
| | | d.order_num, |
| | | d.leader, |
| | | d.status as dept_status, |
| | | d.email as dept_email, |
| | | d.create_time as dept_cteate_time, |
| | | r.role_id, |
| | | r.role_name, |
| | | r.role_key, |
| | | r.role_sort, |
| | | r.data_scope, |
| | | r.status as role_status |
| | | from sys_user u |
| | | left join sys_dept d on u.dept_id = d.dept_id |
| | | left join sys_user_role sur on u.user_id = sur.user_id |
| | | left join sys_role r on r.role_id = sur.role_id |
| | | </sql> |
| | | |
| | | <select id="selectPageUserList" resultMap="SysUserResult"> |
| | | select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, |
| | | u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, |
| | | d.dept_name, d.leader, u1.user_name as leaderName |
| | | select |
| | | <if test="ew.getSqlSelect != null"> |
| | | ${ew.getSqlSelect} |
| | | </if> |
| | | <if test="ew.getSqlSelect == null"> |
| | | u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, |
| | | u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark |
| | | </if> |
| | | from sys_user u |
| | | left join sys_dept d on u.dept_id = d.dept_id |
| | | left join sys_user u1 on u1.user_id = d.leader |
| | | ${ew.getCustomSqlSegment} |
| | | </select> |
| | | |
| | | <select id="selectUserList" resultMap="SysUserResult"> |
| | | select |
| | | <if test="ew.getSqlSelect != null"> |
| | | ${ew.getSqlSelect} |
| | | </if> |
| | | <if test="ew.getSqlSelect == null"> |
| | | u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, |
| | | u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark |
| | | </if> |
| | | from sys_user u |
| | | ${ew.getCustomSqlSegment} |
| | | </select> |
| | | |
| | | <select id="selectUserExportList" resultMap="SysUserExportResult"> |
| | | select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, |
| | | u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, |
| | | d.dept_name, d.leader, u1.user_name as leaderName |
| | |
| | | ${ew.getCustomSqlSegment} |
| | | </select> |
| | | |
| | | <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.user_name = #{userName} |
| | | </select> |
| | | |
| | | <select id="selectUserByPhonenumber" parameterType="String" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.phonenumber = #{phonenumber} |
| | | </select> |
| | | |
| | | <select id="selectUserByEmail" parameterType="String" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.email = #{email} |
| | | </select> |
| | | |
| | | <select id="selectUserById" parameterType="Long" resultMap="SysUserResult"> |
| | | <include refid="selectUserVo"/> |
| | | where u.del_flag = '0' and u.user_id = #{userId} |
| | | <select id="countUserById" resultType="Long"> |
| | | select count(*) from sys_user where del_flag = '0' and user_id = #{userId} |
| | | </select> |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?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"> |
| | | <parent> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <packaging>jar</packaging> |
| | | <artifactId>ruoyi-workflow</artifactId> |
| | | |
| | | <description> |
| | | 工使µæ¨¡å |
| | | </description> |
| | | |
| | | <dependencies> |
| | | |
| | | <!--å¼å
¥flowableä¾èµ--> |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-spring-boot-autoconfigure</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-spring-security</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-spring-configurator</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-spring-boot-starter-actuator</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- ç»å¶flowableæµç¨å¾ --> |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-image-generator</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- flowable json è½¬æ¢ --> |
| | | <dependency> |
| | | <groupId>org.flowable</groupId> |
| | | <artifactId>flowable-json-converter</artifactId> |
| | | <version>6.8.0</version> |
| | | </dependency> |
| | | |
| | | <!-- svg转pngå¾çå·¥å
·--> |
| | | <dependency> |
| | | <groupId>org.apache.xmlgraphics</groupId> |
| | | <artifactId>batik-all</artifactId> |
| | | <version>1.10</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>xalan</groupId> |
| | | <artifactId>xalan</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-websocket</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-mail</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-sms</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-mybatis</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-web</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-log</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-idempotent</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-excel</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-translation</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.dromara</groupId> |
| | | <artifactId>ruoyi-common-tenant</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.annotation; |
| | | |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * æµç¨ä»»å¡ç嬿³¨è§£ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | @Target({ElementType.TYPE}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Inherited |
| | | public @interface FlowListenerAnnotation { |
| | | |
| | | /** |
| | | * æµç¨å®ä¹key |
| | | */ |
| | | String processDefinitionKey(); |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | String taskDefId() default ""; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.common.constant; |
| | | |
| | | |
| | | /** |
| | | * 工使µå¸¸é |
| | | * |
| | | * @author may |
| | | */ |
| | | public interface FlowConstant { |
| | | |
| | | String MESSAGE_CURRENT_TASK_IS_NULL = "å½åä»»å¡ä¸åå¨æä½ ä¸æ¯ä»»å¡åç人ï¼"; |
| | | |
| | | String MESSAGE_SUSPENDED = "å½åä»»å¡å·²æèµ·ä¸å¯å®¡æ¹ï¼"; |
| | | |
| | | /** |
| | | * è¿çº¿ |
| | | */ |
| | | String SEQUENCE_FLOW = "sequenceFlow"; |
| | | |
| | | /** |
| | | * å¹¶è¡ç½å
³ |
| | | */ |
| | | String PARALLEL_GATEWAY = "parallelGateway"; |
| | | |
| | | /** |
| | | * æå®ç½å
³ |
| | | */ |
| | | String EXCLUSIVE_GATEWAY = "exclusiveGateway"; |
| | | |
| | | /** |
| | | * å
å«ç½å
³ |
| | | */ |
| | | String INCLUSIVE_GATEWAY = "inclusiveGateway"; |
| | | |
| | | /** |
| | | * ç»æèç¹ |
| | | */ |
| | | String END_EVENT = "endEvent"; |
| | | |
| | | |
| | | /** |
| | | * æµç¨å§æ´¾æ è¯ |
| | | */ |
| | | String PENDING = "PENDING"; |
| | | |
| | | /** |
| | | * åé人æ è¯ |
| | | */ |
| | | String CANDIDATE = "candidate"; |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡æ»æ° |
| | | */ |
| | | String NUMBER_OF_INSTANCES = "nrOfInstances"; |
| | | |
| | | /** |
| | | * æ£å¨æ§è¡çä¼ç¾æ»æ° |
| | | */ |
| | | String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances"; |
| | | |
| | | /** |
| | | * 已宿çä¼ç¾ä»»å¡æ»æ° |
| | | */ |
| | | String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances"; |
| | | |
| | | /** |
| | | * 循ç¯çç´¢å¼å¼ï¼å¯ä»¥ä½¿ç¨elementIndexVariable屿§ä¿®æ¹loopCounterçåéå |
| | | */ |
| | | String LOOP_COUNTER = "loopCounter"; |
| | | |
| | | String ZIP = "ZIP"; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å¯¹è±¡ |
| | | */ |
| | | String PROCESS_INSTANCE_VO = "processInstanceVo"; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½® |
| | | */ |
| | | String WF_DEFINITION_CONFIG_VO = "wfDefinitionConfigVo"; |
| | | |
| | | /** |
| | | * èç¹é
ç½® |
| | | */ |
| | | String WF_NODE_CONFIG_VO = "wfNodeConfigVo"; |
| | | |
| | | /** |
| | | * æµç¨å起人 |
| | | */ |
| | | String INITIATOR = "initiator"; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | String PROCESS_INSTANCE_ID = "processInstanceId"; |
| | | |
| | | /** |
| | | * ä¸å¡id |
| | | */ |
| | | String BUSINESS_KEY = "businessKey"; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | String PROCESS_DEFINITION_ID = "processDefinitionId"; |
| | | |
| | | /** |
| | | * å¼å¯è·³è¿è¡¨è¾¾å¼åé |
| | | */ |
| | | String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED"; |
| | | |
| | | /** |
| | | * æ¨¡åæ è¯keyå½åè§èæ£åè¡¨è¾¾å¼ |
| | | */ |
| | | String MODEL_KEY_PATTERN = "^[a-zA-Z][a-zA-Z0-9_]{0,254}$"; |
| | | |
| | | /** |
| | | * ç¨æ·ä»»å¡ |
| | | */ |
| | | String USER_TASK = "userTask"; |
| | | |
| | | /** |
| | | * ä¼ç¾ |
| | | */ |
| | | String MULTI_INSTANCE = "multiInstance"; |
| | | |
| | | /** |
| | | * æ¯ |
| | | */ |
| | | String TRUE = "0"; |
| | | |
| | | /** |
| | | * å¦ |
| | | */ |
| | | String FALSE = "1"; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.common.enums; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * ä¸å¡ç¶ææä¸¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum BusinessStatusEnum { |
| | | /** |
| | | * å·²æ¤é |
| | | */ |
| | | CANCEL("cancel", "å·²æ¤é"), |
| | | /** |
| | | * è稿 |
| | | */ |
| | | DRAFT("draft", "è稿"), |
| | | /** |
| | | * å¾
å®¡æ ¸ |
| | | */ |
| | | WAITING("waiting", "å¾
å®¡æ ¸"), |
| | | /** |
| | | * 已宿 |
| | | */ |
| | | FINISH("finish", "已宿"), |
| | | /** |
| | | * å·²ä½åº |
| | | */ |
| | | INVALID("invalid", "å·²ä½åº"), |
| | | /** |
| | | * å·²éå |
| | | */ |
| | | BACK("back", "å·²éå"), |
| | | /** |
| | | * å·²ç»æ¢ |
| | | */ |
| | | TERMINATION("termination", "å·²ç»æ¢"); |
| | | |
| | | /** |
| | | * ç¶æ |
| | | */ |
| | | private final String status; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private final String desc; |
| | | |
| | | /** |
| | | * è·åä¸å¡ç¶æ |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static String findByStatus(String status) { |
| | | if (StringUtils.isBlank(status)) { |
| | | return StrUtil.EMPTY; |
| | | } |
| | | return Arrays.stream(BusinessStatusEnum.values()) |
| | | .filter(statusEnum -> statusEnum.getStatus().equals(status)) |
| | | .findFirst() |
| | | .map(BusinessStatusEnum::getDesc) |
| | | .orElse(StrUtil.EMPTY); |
| | | } |
| | | |
| | | /** |
| | | * å¯å¨æµç¨æ ¡éª |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static void checkStartStatus(String status) { |
| | | if (WAITING.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²æäº¤è¿ç³è¯·,æ£å¨å®¡æ¹ä¸ï¼"); |
| | | } else if (FINISH.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²å®æç³è¯·ï¼"); |
| | | } else if (INVALID.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ä½åºï¼"); |
| | | } else if (TERMINATION.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ç»æ¢ï¼"); |
| | | } else if (StringUtils.isBlank(status)) { |
| | | throw new ServiceException("æµç¨ç¶æä¸ºç©ºï¼"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¤éæµç¨æ ¡éª |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static void checkCancelStatus(String status) { |
| | | if (CANCEL.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²æ¤éï¼"); |
| | | } else if (FINISH.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²å®æç³è¯·ï¼"); |
| | | } else if (INVALID.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ä½åºï¼"); |
| | | } else if (TERMINATION.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ç»æ¢ï¼"); |
| | | } else if (BACK.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²éåï¼"); |
| | | } else if (StringUtils.isBlank(status)) { |
| | | throw new ServiceException("æµç¨ç¶æä¸ºç©ºï¼"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * é©³åæµç¨æ ¡éª |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static void checkBackStatus(String status) { |
| | | if (BACK.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²éåï¼"); |
| | | } else if (FINISH.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²å®æç³è¯·ï¼"); |
| | | } else if (INVALID.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ä½åºï¼"); |
| | | } else if (TERMINATION.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ç»æ¢ï¼"); |
| | | } else if (CANCEL.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²æ¤éï¼"); |
| | | } else if (StringUtils.isBlank(status)) { |
| | | throw new ServiceException("æµç¨ç¶æä¸ºç©ºï¼"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä½åº,ç»æ¢æµç¨æ ¡éª |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static void checkInvalidStatus(String status) { |
| | | if (FINISH.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²å®æç³è¯·ï¼"); |
| | | } else if (INVALID.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ä½åºï¼"); |
| | | } else if (TERMINATION.getStatus().equals(status)) { |
| | | throw new ServiceException("è¯¥åæ®å·²ç»æ¢ï¼"); |
| | | } else if (StringUtils.isBlank(status)) { |
| | | throw new ServiceException("æµç¨ç¶æä¸ºç©ºï¼"); |
| | | } |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.common.enums; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * ä»»å¡ç¶ææä¸¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum FormTypeEnum { |
| | | /** |
| | | * èªå®ä¹è¡¨å |
| | | */ |
| | | STATIC("static", "èªå®ä¹è¡¨å"), |
| | | /** |
| | | * å¨æè¡¨å |
| | | */ |
| | | DYNAMIC("dynamic", "å¨æè¡¨å"); |
| | | |
| | | /** |
| | | * ç±»å |
| | | */ |
| | | private final String type; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private final String desc; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | * |
| | | * @param formType 表åç±»å |
| | | */ |
| | | public static String findByType(String formType) { |
| | | if (StringUtils.isBlank(formType)) { |
| | | return StrUtil.EMPTY; |
| | | } |
| | | |
| | | return Arrays.stream(FormTypeEnum.values()) |
| | | .filter(statusEnum -> statusEnum.getType().equals(formType)) |
| | | .findFirst() |
| | | .map(FormTypeEnum::getDesc) |
| | | .orElse(StrUtil.EMPTY); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.common.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»åæä¸¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MessageTypeEnum { |
| | | /** |
| | | * ç«å
ä¿¡ |
| | | */ |
| | | SYSTEM_MESSAGE("1", "ç«å
ä¿¡"), |
| | | /** |
| | | * é®ç®± |
| | | */ |
| | | EMAIL_MESSAGE("2", "é®ç®±"), |
| | | /** |
| | | * çä¿¡ |
| | | */ |
| | | SMS_MESSAGE("3", "çä¿¡"); |
| | | |
| | | private final String code; |
| | | |
| | | private final String desc; |
| | | |
| | | private final static Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = new ConcurrentHashMap<>(MessageTypeEnum.values().length); |
| | | |
| | | static { |
| | | for (MessageTypeEnum messageType : MessageTypeEnum.values()) { |
| | | MESSAGE_TYPE_ENUM_MAP.put(messageType.code, messageType); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ¶æ¯ç±»å code è·å MessageTypeEnum |
| | | * @param code æ¶æ¯ç±»åcode |
| | | * @return MessageTypeEnum |
| | | */ |
| | | public static MessageTypeEnum getByCode(String code) { |
| | | return MESSAGE_TYPE_ENUM_MAP.get(code); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.common.enums; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * ä»»å¡ç¶ææä¸¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum TaskStatusEnum { |
| | | /** |
| | | * æ¤é |
| | | */ |
| | | CANCEL("cancel", "æ¤é"), |
| | | /** |
| | | * éè¿ |
| | | */ |
| | | PASS("pass", "éè¿"), |
| | | /** |
| | | * å¾
å®¡æ ¸ |
| | | */ |
| | | WAITING("waiting", "å¾
å®¡æ ¸"), |
| | | /** |
| | | * ä½åº |
| | | */ |
| | | INVALID("invalid", "ä½åº"), |
| | | /** |
| | | * éå |
| | | */ |
| | | BACK("back", "éå"), |
| | | /** |
| | | * ç»æ¢ |
| | | */ |
| | | TERMINATION("termination", "ç»æ¢"), |
| | | /** |
| | | * 转å |
| | | */ |
| | | TRANSFER("transfer", "转å"), |
| | | /** |
| | | * å§æ |
| | | */ |
| | | PENDING("pending", "å§æ"), |
| | | /** |
| | | * æé |
| | | */ |
| | | COPY("copy", "æé"), |
| | | /** |
| | | * å ç¾ |
| | | */ |
| | | SIGN("sign", "å ç¾"), |
| | | /** |
| | | * åç¾ |
| | | */ |
| | | SIGN_OFF("sign_off", "åç¾"), |
| | | /** |
| | | * è¶
æ¶ |
| | | */ |
| | | TIMEOUT("timeout", "è¶
æ¶"); |
| | | |
| | | /** |
| | | * ç¶æ |
| | | */ |
| | | private final String status; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private final String desc; |
| | | |
| | | /** |
| | | * ä»»å¡ä¸å¡ç¶æ |
| | | * |
| | | * @param status ç¶æ |
| | | */ |
| | | public static String findByStatus(String status) { |
| | | if (StringUtils.isBlank(status)) { |
| | | return StrUtil.EMPTY; |
| | | } |
| | | |
| | | return Arrays.stream(TaskStatusEnum.values()) |
| | | .filter(statusEnum -> statusEnum.getStatus().equals(status)) |
| | | .findFirst() |
| | | .map(TaskStatusEnum::getDesc) |
| | | .orElse(StrUtil.EMPTY); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.bo.ModelBo; |
| | | import org.dromara.workflow.domain.vo.ModelVo; |
| | | import org.dromara.workflow.service.IActModelService; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.repository.Model; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 模åç®¡ç æ§å¶å± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/model") |
| | | public class ActModelController extends BaseController { |
| | | |
| | | private final RepositoryService repositoryService; |
| | | |
| | | private final IActModelService actModelService; |
| | | |
| | | |
| | | /** |
| | | * å页æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param modelBo 模ååæ° |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery) { |
| | | return actModelService.page(modelBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æ¨¡å |
| | | * |
| | | * @param modelBo 模å请æ±å¯¹è±¡ |
| | | */ |
| | | @Log(title = "模å管ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/save") |
| | | public R<Void> saveNewModel(@Validated(AddGroup.class) @RequestBody ModelBo modelBo) { |
| | | return toAjax(actModelService.saveNewModel(modelBo)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param id 模åid |
| | | */ |
| | | @GetMapping("/getInfo/{id}") |
| | | public R<ModelVo> getInfo(@NotBlank(message = "模åidä¸è½ä¸ºç©º") @PathVariable String id) { |
| | | return R.ok(actModelService.getInfo(id)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æ¨¡åä¿¡æ¯ |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | */ |
| | | @Log(title = "模å管ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping(value = "/update") |
| | | public R<Void> update(@RequestBody ModelBo modelBo) { |
| | | return toAjax(actModelService.update(modelBo)); |
| | | } |
| | | |
| | | /** |
| | | * ç¼è¾XMl模å |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | */ |
| | | @Log(title = "模å管ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping(value = "/editModelXml") |
| | | public R<Void> editModel(@Validated(EditGroup.class) @RequestBody ModelBo modelBo) { |
| | | return toAjax(actModelService.editModelXml(modelBo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨æ¨¡å |
| | | * |
| | | * @param ids 模åid |
| | | */ |
| | | @Log(title = "模å管ç", businessType = BusinessType.DELETE) |
| | | @RepeatSubmit() |
| | | @DeleteMapping("/{ids}") |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R<Void> delete(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") @PathVariable String[] ids) { |
| | | Arrays.stream(ids).parallel().forEachOrdered(repositoryService::deleteModel); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 模åé¨ç½² |
| | | * |
| | | * @param id 模åid |
| | | */ |
| | | @Log(title = "模å管ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/modelDeploy/{id}") |
| | | public R<Void> deploy(@NotBlank(message = "模åidä¸è½ä¸ºç©º") @PathVariable("id") String id) { |
| | | return toAjax(actModelService.modelDeploy(id)); |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæ¨¡åzipå缩å
|
| | | * |
| | | * @param modelIds 模åid |
| | | * @param response ç¸åº |
| | | */ |
| | | @GetMapping("/export/zip/{modelIds}") |
| | | public void exportZip(@NotEmpty(message = "模åidä¸è½ä¸ºç©º") @PathVariable List<String> modelIds, |
| | | HttpServletResponse response) { |
| | | actModelService.exportZip(modelIds, response); |
| | | } |
| | | |
| | | /** |
| | | * å¤å¶æ¨¡å |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | */ |
| | | @PostMapping("/copyModel") |
| | | public R<Void> copyModel(@RequestBody ModelBo modelBo) { |
| | | return toAjax(actModelService.copyModel(modelBo)); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.bo.ProcessDefinitionBo; |
| | | import org.dromara.workflow.domain.vo.ProcessDefinitionVo; |
| | | import org.dromara.workflow.service.IActProcessDefinitionService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ç®¡ç æ§å¶å± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/processDefinition") |
| | | public class ActProcessDefinitionController extends BaseController { |
| | | |
| | | private final IActProcessDefinitionService actProcessDefinitionService; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo bo, PageQuery pageQuery) { |
| | | return actProcessDefinitionService.page(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å岿µç¨å®ä¹å表 |
| | | * |
| | | * @param key æµç¨å®ä¹key |
| | | */ |
| | | @GetMapping("/getListByKey/{key}") |
| | | public R<List<ProcessDefinitionVo>> getListByKey(@NotEmpty(message = "æµç¨å®ä¹keyä¸è½ä¸ºç©º") @PathVariable String key) { |
| | | return R.ok("æä½æå", actProcessDefinitionService.getListByKey(key)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹å¾ç |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @GetMapping("/definitionImage/{processDefinitionId}") |
| | | public R<String> definitionImage(@PathVariable String processDefinitionId) { |
| | | return R.ok("æä½æå", actProcessDefinitionService.definitionImage(processDefinitionId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹xmlæä»¶ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @GetMapping("/definitionXml/{processDefinitionId}") |
| | | public R<Map<String, Object>> definitionXml(@NotBlank(message = "æµç¨å®ä¹idä¸è½ä¸ºç©º") @PathVariable String processDefinitionId) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | String xmlStr = actProcessDefinitionService.definitionXml(processDefinitionId); |
| | | map.put("xml", Arrays.asList(xmlStr.split("\n"))); |
| | | map.put("xmlStr", xmlStr); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¹ |
| | | * |
| | | * @param deploymentIds é¨ç½²id |
| | | * @param processDefinitionIds æµç¨å®ä¹id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹ç®¡ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{deploymentIds}/{processDefinitionIds}") |
| | | public R<Void> deleteDeployment(@NotNull(message = "æµç¨é¨ç½²idä¸è½ä¸ºç©º") @PathVariable List<String> deploymentIds, |
| | | @NotNull(message = "æµç¨å®ä¹idä¸è½ä¸ºç©º") @PathVariable List<String> processDefinitionIds) { |
| | | return toAjax(actProcessDefinitionService.deleteDeployment(deploymentIds, processDefinitionIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¿æ´»æè
æèµ·æµç¨å®ä¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping("/updateDefinitionState/{processDefinitionId}") |
| | | public R<Void> updateDefinitionState(@NotBlank(message = "æµç¨å®ä¹idä¸è½ä¸ºç©º") @PathVariable String processDefinitionId) { |
| | | return toAjax(actProcessDefinitionService.updateDefinitionState(processDefinitionId)); |
| | | } |
| | | |
| | | /** |
| | | * è¿ç§»æµç¨å®ä¹ |
| | | * |
| | | * @param currentProcessDefinitionId å½åæµç¨å®ä¹id |
| | | * @param fromProcessDefinitionId éè¦è¿ç§»å°çæµç¨å®ä¹id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping("/migrationDefinition/{currentProcessDefinitionId}/{fromProcessDefinitionId}") |
| | | public R<Void> migrationDefinition(@NotBlank(message = "å½åæµç¨å®ä¹id") @PathVariable String currentProcessDefinitionId, |
| | | @NotBlank(message = "éè¦è¿ç§»å°çæµç¨å®ä¹id") @PathVariable String fromProcessDefinitionId) { |
| | | return toAjax(actProcessDefinitionService.migrationDefinition(currentProcessDefinitionId, fromProcessDefinitionId)); |
| | | } |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è½¬æ¢ä¸ºæ¨¡å |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping("/convertToModel/{processDefinitionId}") |
| | | public R<Void> convertToModel(@NotEmpty(message = "æµç¨å®ä¹idä¸è½ä¸ºç©º") @PathVariable String processDefinitionId) { |
| | | return toAjax(actProcessDefinitionService.convertToModel(processDefinitionId)); |
| | | } |
| | | |
| | | /** |
| | | * éè¿zipæxmlé¨ç½²æµç¨å®ä¹ |
| | | * |
| | | * @param file æä»¶ |
| | | * @param categoryCode åç±» |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹ç®¡ç", businessType = BusinessType.INSERT) |
| | | @PostMapping("/deployByFile") |
| | | public void deployByFile(@RequestParam("file") MultipartFile file, @RequestParam("categoryCode") String categoryCode) { |
| | | actProcessDefinitionService.deployByFile(file, categoryCode); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.bo.ProcessInstanceBo; |
| | | import org.dromara.workflow.domain.bo.ProcessInvalidBo; |
| | | import org.dromara.workflow.domain.bo.TaskUrgingBo; |
| | | import org.dromara.workflow.domain.vo.ActHistoryInfoVo; |
| | | import org.dromara.workflow.domain.vo.ProcessInstanceVo; |
| | | import org.dromara.workflow.service.IActProcessInstanceService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ç®¡ç æ§å¶å± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/processInstance") |
| | | public class ActProcessInstanceController extends BaseController { |
| | | |
| | | private final IActProcessInstanceService actProcessInstanceService; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢æ£å¨è¿è¡çæµç¨å®ä¾ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @GetMapping("/getPageByRunning") |
| | | public TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | return actProcessInstanceService.getPageByRunning(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å·²ç»æçæµç¨å®ä¾ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @GetMapping("/getPageByFinish") |
| | | public TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | return actProcessInstanceService.getPageByFinish(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @GetMapping("/getHistoryImage/{processInstanceId}") |
| | | public R<String> getHistoryImage(@NotBlank(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String processInstanceId) { |
| | | return R.ok("æä½æå", actProcessInstanceService.getHistoryImage(processInstanceId)); |
| | | } |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾è¿è¡ä¸ï¼åå²çèç¹ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @GetMapping("/getHistoryList/{processInstanceId}") |
| | | public R<Map<String, Object>> getHistoryList(@NotBlank(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String processInstanceId) { |
| | | return R.ok("æä½æå", actProcessInstanceService.getHistoryList(processInstanceId)); |
| | | } |
| | | |
| | | /** |
| | | * è·å审æ¹è®°å½ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @GetMapping("/getHistoryRecord/{processInstanceId}") |
| | | public R<List<ActHistoryInfoVo>> getHistoryRecord(@NotBlank(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String processInstanceId) { |
| | | return R.ok(actProcessInstanceService.getHistoryRecord(processInstanceId)); |
| | | } |
| | | |
| | | /** |
| | | * ä½åºæµç¨å®ä¾ï¼ä¸ä¼å é¤åå²è®°å½(å é¤è¿è¡ä¸çå®ä¾) |
| | | * |
| | | * @param processInvalidBo åæ° |
| | | */ |
| | | @Log(title = "æµç¨å®ä¾ç®¡ç", businessType = BusinessType.DELETE) |
| | | @RepeatSubmit() |
| | | @PostMapping("/deleteRunInstance") |
| | | public R<Void> deleteRunInstance(@Validated(AddGroup.class) @RequestBody ProcessInvalidBo processInvalidBo) { |
| | | return toAjax(actProcessInstanceService.deleteRunInstance(processInvalidBo)); |
| | | } |
| | | |
| | | /** |
| | | * è¿è¡ä¸çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¾ç®¡ç", businessType = BusinessType.DELETE) |
| | | @RepeatSubmit() |
| | | @DeleteMapping("/deleteRunAndHisInstance/{processInstanceIds}") |
| | | public R<Void> deleteRunAndHisInstance(@NotNull(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String[] processInstanceIds) { |
| | | return toAjax(actProcessInstanceService.deleteRunAndHisInstance(Arrays.asList(processInstanceIds))); |
| | | } |
| | | |
| | | /** |
| | | * 已宿çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¾ç®¡ç", businessType = BusinessType.DELETE) |
| | | @RepeatSubmit() |
| | | @DeleteMapping("/deleteFinishAndHisInstance/{processInstanceIds}") |
| | | public R<Void> deleteFinishAndHisInstance(@NotNull(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String[] processInstanceIds) { |
| | | return toAjax(actProcessInstanceService.deleteFinishAndHisInstance(Arrays.asList(processInstanceIds))); |
| | | } |
| | | |
| | | /** |
| | | * æ¤éæµç¨ç³è¯· |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @Log(title = "æµç¨å®ä¾ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/cancelProcessApply/{processInstanceId}") |
| | | public R<Void> cancelProcessApply(@NotBlank(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º") @PathVariable String processInstanceId) { |
| | | return toAjax(actProcessInstanceService.cancelProcessApply(processInstanceId)); |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å½åç»å½äººåæ® |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @GetMapping("/getPageByCurrent") |
| | | public TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | return actProcessInstanceService.getPageByCurrent(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * ä»»å¡å¬å(ç»å½åä»»å¡åç人åéç«å
ä¿¡ï¼é®ä»¶ï¼çä¿¡ç) |
| | | * |
| | | * @param taskUrgingBo ä»»å¡å¬å |
| | | */ |
| | | @Log(title = "æµç¨å®ä¾ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/taskUrging") |
| | | public R<Void> taskUrging(@RequestBody TaskUrgingBo taskUrgingBo) { |
| | | return toAjax(actProcessInstanceService.taskUrging(taskUrgingBo)); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.WfTaskBackNode; |
| | | import org.dromara.workflow.domain.bo.*; |
| | | import org.dromara.workflow.domain.vo.TaskVo; |
| | | import org.dromara.workflow.domain.vo.VariableVo; |
| | | import org.dromara.workflow.service.IActTaskService; |
| | | import org.dromara.workflow.service.IWfTaskBackNodeService; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.engine.TaskService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ä»»å¡ç®¡ç æ§å¶å± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/task") |
| | | public class ActTaskController extends BaseController { |
| | | |
| | | private final IActTaskService actTaskService; |
| | | |
| | | private final TaskService taskService; |
| | | |
| | | private final IWfTaskBackNodeService wfTaskBackNodeService; |
| | | |
| | | |
| | | /** |
| | | * å¯å¨ä»»å¡ |
| | | * |
| | | * @param startProcessBo å¯å¨æµç¨åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/startWorkFlow") |
| | | public R<Map<String, Object>> startWorkFlow(@Validated(AddGroup.class) @RequestBody StartProcessBo startProcessBo) { |
| | | Map<String, Object> map = actTaskService.startWorkFlow(startProcessBo); |
| | | return R.ok("æäº¤æå", map); |
| | | } |
| | | |
| | | /** |
| | | * åçä»»å¡ |
| | | * |
| | | * @param completeTaskBo åçä»»å¡åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/completeTask") |
| | | public R<Void> completeTask(@Validated(AddGroup.class) @RequestBody CompleteTaskBo completeTaskBo) { |
| | | return toAjax(actTaskService.completeTask(completeTaskBo)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @GetMapping("/getPageByTaskWait") |
| | | public TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery) { |
| | | return actTaskService.getPageByTaskWait(taskBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @GetMapping("/getPageByAllTaskWait") |
| | | public TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery) { |
| | | return actTaskService.getPageByAllTaskWait(taskBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @GetMapping("/getPageByTaskFinish") |
| | | public TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery) { |
| | | return actTaskService.getPageByTaskFinish(taskBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çæé |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @GetMapping("/getPageByTaskCopy") |
| | | public TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery) { |
| | | return actTaskService.getPageByTaskCopy(taskBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @GetMapping("/getPageByAllTaskFinish") |
| | | public TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery) { |
| | | return actTaskService.getPageByAllTaskFinish(taskBo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * ç¾æ¶ï¼æ¾åï¼ä»»å¡ |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/claim/{taskId}") |
| | | public R<Void> claimTask(@NotBlank(message = "ä»»å¡idä¸è½ä¸ºç©º") @PathVariable String taskId) { |
| | | try { |
| | | taskService.claim(taskId, Convert.toStr(LoginHelper.getUserId())); |
| | | return R.ok(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return R.fail("ç¾æ¶ä»»å¡å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å½è¿ï¼æ¾åçï¼ä»»å¡ |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/returnTask/{taskId}") |
| | | public R<Void> returnTask(@NotBlank(message = "ä»»å¡idä¸è½ä¸ºç©º") @PathVariable String taskId) { |
| | | try { |
| | | taskService.setAssignee(taskId, null); |
| | | return R.ok(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return R.fail("å½è¿ä»»å¡å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | * |
| | | * @param delegateBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/delegateTask") |
| | | public R<Void> delegateTask(@Validated({AddGroup.class}) @RequestBody DelegateBo delegateBo) { |
| | | return toAjax(actTaskService.delegateTask(delegateBo)); |
| | | } |
| | | |
| | | /** |
| | | * ç»æ¢ä»»å¡ |
| | | * |
| | | * @param terminationBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.DELETE) |
| | | @RepeatSubmit() |
| | | @PostMapping("/terminationTask") |
| | | public R<Void> terminationTask(@RequestBody TerminationBo terminationBo) { |
| | | return toAjax(actTaskService.terminationTask(terminationBo)); |
| | | } |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * |
| | | * @param transmitBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/transferTask") |
| | | public R<Void> transferTask(@Validated({AddGroup.class}) @RequestBody TransmitBo transmitBo) { |
| | | return toAjax(actTaskService.transferTask(transmitBo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡å ç¾ |
| | | * |
| | | * @param addMultiBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/addMultiInstanceExecution") |
| | | public R<Void> addMultiInstanceExecution(@Validated({AddGroup.class}) @RequestBody AddMultiBo addMultiBo) { |
| | | return toAjax(actTaskService.addMultiInstanceExecution(addMultiBo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡åç¾ |
| | | * |
| | | * @param deleteMultiBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/deleteMultiInstanceExecution") |
| | | public R<Void> deleteMultiInstanceExecution(@Validated({AddGroup.class}) @RequestBody DeleteMultiBo deleteMultiBo) { |
| | | return toAjax(actTaskService.deleteMultiInstanceExecution(deleteMultiBo)); |
| | | } |
| | | |
| | | /** |
| | | * 驳åå®¡æ¹ |
| | | * |
| | | * @param backProcessBo åæ° |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/backProcess") |
| | | public R<String> backProcess(@Validated({AddGroup.class}) @RequestBody BackProcessBo backProcessBo) { |
| | | return R.ok(actTaskService.backProcess(backProcessBo)); |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åä»»å¡ |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @GetMapping("/getTaskById/{taskId}") |
| | | public R<TaskVo> getTaskById(@PathVariable String taskId) { |
| | | return R.ok(QueryUtils.getTask(taskId)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»»å¡åç人 |
| | | * |
| | | * @param taskIds ä»»å¡id |
| | | * @param userId åç人id |
| | | */ |
| | | @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping("/updateAssignee/{taskIds}/{userId}") |
| | | public R<Void> updateAssignee(@PathVariable String[] taskIds, @PathVariable String userId) { |
| | | return toAjax(actTaskService.updateAssignee(taskIds, userId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åé |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @GetMapping("/getInstanceVariable/{taskId}") |
| | | public R<List<VariableVo>> getProcessInstVariable(@PathVariable String taskId) { |
| | | return R.ok(actTaskService.getInstanceVariable(taskId)); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¯é©³åå¾ä»»å¡èç¹ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @GetMapping("/getTaskNodeList/{processInstanceId}") |
| | | public R<List<WfTaskBackNode>> getNodeList(@PathVariable String processInstanceId) { |
| | | return R.ok(CollUtil.reverse(wfTaskBackNodeService.getListByInstanceId(processInstanceId))); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµä»»å¡ç¨æ·éæ©å ç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @GetMapping("/getTaskUserIdsByAddMultiInstance/{taskId}") |
| | | public R<String> getTaskUserIdsByAddMultiInstance(@PathVariable String taskId) { |
| | | return R.ok(actTaskService.getTaskUserIdsByAddMultiInstance(taskId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµéæ©åç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @GetMapping("/getListByDeleteMultiInstance/{taskId}") |
| | | public R<List<TaskVo>> getListByDeleteMultiInstance(@PathVariable String taskId) { |
| | | return R.ok(actTaskService.getListByDeleteMultiInstance(taskId)); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.bo.TestLeaveBo; |
| | | import org.dromara.workflow.domain.vo.TestLeaveVo; |
| | | import org.dromara.workflow.service.ITestLeaveService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 请å |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/demo/leave") |
| | | public class TestLeaveController extends BaseController { |
| | | |
| | | private final ITestLeaveService testLeaveService; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·åå表 |
| | | */ |
| | | @SaCheckPermission("demo:leave:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<TestLeaveVo> list(TestLeaveBo bo, PageQuery pageQuery) { |
| | | return testLeaveService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºè¯·åå表 |
| | | */ |
| | | @SaCheckPermission("demo:leave:export") |
| | | @Log(title = "请å", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(TestLeaveBo bo, HttpServletResponse response) { |
| | | List<TestLeaveVo> list = testLeaveService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "请å", TestLeaveVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·å请å详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @SaCheckPermission("demo:leave:query") |
| | | @GetMapping("/{id}") |
| | | public R<TestLeaveVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long id) { |
| | | return R.ok(testLeaveService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è¯·å |
| | | */ |
| | | @SaCheckPermission("demo:leave:add") |
| | | @Log(title = "请å", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<TestLeaveVo> add(@Validated(AddGroup.class) @RequestBody TestLeaveBo bo) { |
| | | return R.ok(testLeaveService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹è¯·å |
| | | */ |
| | | @SaCheckPermission("demo:leave:edit") |
| | | @Log(title = "请å", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<TestLeaveVo> edit(@Validated(EditGroup.class) @RequestBody TestLeaveBo bo) { |
| | | return R.ok(testLeaveService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤è¯·å |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @SaCheckPermission("demo:leave:remove") |
| | | @Log(title = "请å", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(testLeaveService.deleteWithValidByIds(List.of(ids))); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.workflow.domain.bo.WfCategoryBo; |
| | | import org.dromara.workflow.domain.vo.WfCategoryVo; |
| | | import org.dromara.workflow.service.IWfCategoryService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨åç±» |
| | | * |
| | | * @author may |
| | | * @date 2023-06-28 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/category") |
| | | public class WfCategoryController extends BaseController { |
| | | |
| | | private final IWfCategoryService wfCategoryService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»å表 |
| | | */ |
| | | @SaCheckPermission("workflow:category:list") |
| | | @GetMapping("/list") |
| | | public R<List<WfCategoryVo>> list(WfCategoryBo bo) { |
| | | List<WfCategoryVo> list = wfCategoryService.queryList(bo); |
| | | return R.ok(list); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæµç¨åç±»å表 |
| | | */ |
| | | @SaCheckPermission("workflow:category:export") |
| | | @Log(title = "æµç¨åç±»", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(WfCategoryBo bo, HttpServletResponse response) { |
| | | List<WfCategoryVo> list = wfCategoryService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "æµç¨åç±»", WfCategoryVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨å类详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @SaCheckPermission("workflow:category:query") |
| | | @GetMapping("/{id}") |
| | | public R<WfCategoryVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long id) { |
| | | return R.ok(wfCategoryService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨åç±» |
| | | */ |
| | | @SaCheckPermission("workflow:category:add") |
| | | @Log(title = "æµç¨åç±»", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody WfCategoryBo bo) { |
| | | return toAjax(wfCategoryService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨åç±» |
| | | */ |
| | | @SaCheckPermission("workflow:category:edit") |
| | | @Log(title = "æµç¨åç±»", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfCategoryBo bo) { |
| | | return toAjax(wfCategoryService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨åç±» |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @SaCheckPermission("workflow:category:remove") |
| | | @Log(title = "æµç¨åç±»", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(wfCategoryService.deleteWithValidByIds(List.of(ids), true)); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import java.util.List; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import jakarta.validation.constraints.*; |
| | | import org.dromara.workflow.domain.bo.WfDefinitionConfigBo; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.workflow.service.IWfDefinitionConfigService; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/definitionConfig") |
| | | public class WfDefinitionConfigController extends BaseController { |
| | | |
| | | private final IWfDefinitionConfigService wfDefinitionConfigService; |
| | | |
| | | |
| | | /** |
| | | * è·åæµç¨å®ä¹é
置详ç»ä¿¡æ¯ |
| | | * |
| | | * @param definitionId ä¸»é® |
| | | */ |
| | | @GetMapping("/getByDefId/{definitionId}") |
| | | public R<WfDefinitionConfigVo> getByDefId(@NotBlank(message = "æµç¨å®ä¹IDä¸è½ä¸ºç©º") |
| | | @PathVariable String definitionId) { |
| | | return R.ok(wfDefinitionConfigService.getByDefId(definitionId)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨å®ä¹é
ç½® |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹é
ç½®", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping("/saveOrUpdate") |
| | | public R<Void> saveOrUpdate(@Validated(AddGroup.class) @RequestBody WfDefinitionConfigBo bo) { |
| | | return toAjax(wfDefinitionConfigService.saveOrUpdate(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¹é
ç½® |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @Log(title = "æµç¨å®ä¹é
ç½®", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(wfDefinitionConfigService.deleteByIds(List.of(ids))); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½®æé¤å½åæ¥è¯¢çæµç¨å®ä¹ |
| | | * |
| | | * @param tableName 表å |
| | | * @param definitionId æµç¨å®ä¹id |
| | | */ |
| | | @GetMapping("/getByTableNameNotDefId/{tableName}/{definitionId}") |
| | | public R<List<WfDefinitionConfigVo>> getByTableNameNotDefId(@NotBlank(message = "表åä¸è½ä¸ºç©º") @PathVariable String tableName, |
| | | @NotBlank(message = "æµç¨å®ä¹IDä¸è½ä¸ºç©º") @PathVariable String definitionId) { |
| | | return R.ok(wfDefinitionConfigService.getByTableNameNotDefId(tableName, definitionId)); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.controller; |
| | | |
| | | import java.util.List; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.*; |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | | import org.dromara.workflow.domain.vo.WfFormManageVo; |
| | | import org.dromara.workflow.domain.bo.WfFormManageBo; |
| | | import org.dromara.workflow.service.IWfFormManageService; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | |
| | | /** |
| | | * 表å管ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/workflow/formManage") |
| | | public class WfFormManageController extends BaseController { |
| | | |
| | | private final IWfFormManageService wfFormManageService; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<WfFormManageVo> list(WfFormManageBo bo, PageQuery pageQuery) { |
| | | return wfFormManageService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:list") |
| | | @GetMapping("/list/selectList") |
| | | public R<List<WfFormManageVo>> selectList() { |
| | | return R.ok(wfFormManageService.selectList()); |
| | | } |
| | | |
| | | /** |
| | | * 导åºè¡¨å管çå表 |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:export") |
| | | @Log(title = "表å管ç", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(WfFormManageBo bo, HttpServletResponse response) { |
| | | List<WfFormManageVo> list = wfFormManageService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "表å管ç", WfFormManageVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·å表å管ç详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:query") |
| | | @GetMapping("/{id}") |
| | | public R<WfFormManageVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long id) { |
| | | return R.ok(wfFormManageService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è¡¨å管ç |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:add") |
| | | @Log(title = "表å管ç", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody WfFormManageBo bo) { |
| | | return toAjax(wfFormManageService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹è¡¨å管ç |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:edit") |
| | | @Log(title = "表å管ç", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfFormManageBo bo) { |
| | | return toAjax(wfFormManageService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤è¡¨å管ç |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @SaCheckPermission("workflow:formManage:remove") |
| | | @Log(title = "表å管ç", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(wfFormManageService.deleteByIds(List.of(ids))); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å¯¹è±¡ act_hi_procinst |
| | | * |
| | | * @author may |
| | | * @date 2023-07-22 |
| | | */ |
| | | @Data |
| | | @TableName("act_hi_procinst") |
| | | public class ActHiProcinst implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableId(value = "ID_") |
| | | private String id; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "REV_") |
| | | private Long rev; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "PROC_INST_ID_") |
| | | private String procInstId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "BUSINESS_KEY_") |
| | | private String businessKey; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "PROC_DEF_ID_") |
| | | private String procDefId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "START_TIME_") |
| | | private Date startTime; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "END_TIME_") |
| | | private Date endTime; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "DURATION_") |
| | | private Long duration; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "START_USER_ID_") |
| | | private String startUserId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "START_ACT_ID_") |
| | | private String startActId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "END_ACT_ID_") |
| | | private String endActId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "SUPER_PROCESS_INSTANCE_ID_") |
| | | private String superProcessInstanceId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "DELETE_REASON_") |
| | | private String deleteReason; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "TENANT_ID_") |
| | | private String tenantId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "NAME_") |
| | | private String name; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "CALLBACK_ID_") |
| | | private String callbackId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "CALLBACK_TYPE_") |
| | | private String callbackType; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "REFERENCE_ID_") |
| | | private String referenceId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "REFERENCE_TYPE_") |
| | | private String referenceType; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "PROPAGATED_STAGE_INST_ID_") |
| | | private String propagatedStageInstId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "BUSINESS_STATUS_") |
| | | private String businessStatus; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æµç¨åå²ä»»å¡å¯¹è±¡ act_hi_taskinst |
| | | * |
| | | * @author may |
| | | * @date 2024-03-02 |
| | | */ |
| | | @Data |
| | | @TableName("act_hi_taskinst") |
| | | public class ActHiTaskinst implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableId(value = "ID_") |
| | | private String id; |
| | | |
| | | /** |
| | | * çæ¬ |
| | | */ |
| | | @TableField(value = "REV_") |
| | | private Long rev; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | @TableField(value = "PROC_DEF_ID_") |
| | | private String procDefId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "TASK_DEF_ID_") |
| | | private String taskDefId; |
| | | |
| | | /** |
| | | * ä»»å¡èç¹id |
| | | */ |
| | | @TableField(value = "TASK_DEF_KEY_") |
| | | private String taskDefKey; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | @TableField(value = "PROC_INST_ID_") |
| | | private String procInstId; |
| | | |
| | | /** |
| | | * æµç¨æ§è¡id |
| | | */ |
| | | @TableField(value = "EXECUTION_ID") |
| | | private String executionId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "SCOPE_ID_") |
| | | private String scopeId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "SUB_SCOPE_ID_") |
| | | private String subScopeId; |
| | | |
| | | /** |
| | | * å
ç¨å½ååæ®µæ è¯æéç±»å |
| | | */ |
| | | @TableField(value = "SCOPE_TYPE_") |
| | | private String scopeType; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "SCOPE_DEFINITION_ID_") |
| | | private String scopeDefinitionId; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "PROPAGATED_STAGE_INST_ID_") |
| | | private String propagatedStageInstId; |
| | | |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | @TableField(value = "NAME_") |
| | | private String name; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | | */ |
| | | @TableField(value = "PARENT_TASK_ID_") |
| | | private String parentTaskId; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | @TableField(value = "DESCRIPTION_") |
| | | private String description; |
| | | |
| | | /** |
| | | * åç人 |
| | | */ |
| | | @TableField(value = "OWNER_") |
| | | private String owner; |
| | | |
| | | /** |
| | | * åç人 |
| | | */ |
| | | @TableField(value = "ASSIGNEE_") |
| | | private String assignee; |
| | | |
| | | /** |
| | | * å¼å§äºä»¶ |
| | | */ |
| | | @TableField(value = "START_TIME_") |
| | | private Date startTime; |
| | | |
| | | /** |
| | | * è®¤é¢æ¶é´ |
| | | */ |
| | | @TableField(value = "CLAIM_TIME_") |
| | | private Date claimTime; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | @TableField(value = "END_TIME_") |
| | | private Date endTime; |
| | | |
| | | /** |
| | | * æç»æ¶é´ |
| | | */ |
| | | @TableField(value = "DURATION_") |
| | | private Long duration; |
| | | |
| | | /** |
| | | * å é¤åå |
| | | */ |
| | | @TableField(value = "DELETE_REASON_") |
| | | private String deleteReason; |
| | | |
| | | /** |
| | | * ä¼å
级 |
| | | */ |
| | | @TableField(value = "PRIORITY_") |
| | | private Long priority; |
| | | |
| | | /** |
| | | * å°ææ¶é´ |
| | | */ |
| | | @TableField(value = "DUE_DATE_") |
| | | private Date dueDate; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableField(value = "FORM_KEY_") |
| | | private String formKey; |
| | | |
| | | /** |
| | | * åç±» |
| | | */ |
| | | @TableField(value = "CATEGORY_") |
| | | private String category; |
| | | |
| | | /** |
| | | * æåä¿®æ¹æ¶é´ |
| | | */ |
| | | @TableField(value = "LAST_UPDATED_TIME_") |
| | | private Date lastUpdatedTime; |
| | | |
| | | /** |
| | | * ç§æ·id |
| | | */ |
| | | @TableField(value = "TENANT_ID_") |
| | | private String tenantId; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | |
| | | import java.io.Serial; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 请å对象 test_leave |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("test_leave") |
| | | public class TestLeave extends BaseEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 请åç±»å |
| | | */ |
| | | private String leaveType; |
| | | |
| | | /** |
| | | * å¼å§æ¶é´ |
| | | */ |
| | | private Date startDate; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | private Date endDate; |
| | | |
| | | /** |
| | | * 请åå¤©æ° |
| | | */ |
| | | private Integer leaveDays; |
| | | |
| | | /** |
| | | * 请ååå |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æµç¨å类对象 wf_category |
| | | * |
| | | * @author may |
| | | * @date 2023-06-27 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_category") |
| | | public class WfCategory extends TenantEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | */ |
| | | private String categoryName; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | private String categoryCode; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | | */ |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | private Long sortNum; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
置对象 wf_definition_config |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_definition_config") |
| | | public class WfDefinitionConfig extends BaseEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表å |
| | | */ |
| | | private String tableName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ID |
| | | */ |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æµç¨KEY |
| | | */ |
| | | private String processKey; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * 表å管ç对象 wf_form_manage |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_form_manage") |
| | | public class WfFormManage extends TenantEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private String formType; |
| | | |
| | | /** |
| | | * è·¯ç±å°å/表åID |
| | | */ |
| | | private String router; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * èç¹é
置对象 wf_node_config |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_node_config") |
| | | public class WfNodeConfig extends TenantEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表åid |
| | | */ |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private String formType; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | private String nodeId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç³è¯·äººèç¹ ï¼0æ¯ 1å¦ï¼ |
| | | */ |
| | | private String applyUserTask; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.tenant.core.TenantEntity; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * èç¹é©³åè®°å½ wf_task_back_node |
| | | * |
| | | * @author may |
| | | * @date 2024-03-13 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("wf_task_back_node") |
| | | public class WfTaskBackNode extends TenantEntity { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * å®ä¾id |
| | | */ |
| | | private String instanceId; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | private String nodeId; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | private Integer orderNo; |
| | | |
| | | /** |
| | | * èç¹ç±»å |
| | | */ |
| | | private String taskType; |
| | | |
| | | /** |
| | | * åç人 |
| | | */ |
| | | private String assignee; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å ç¾åæ°è¯·æ± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class AddMultiBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ID |
| | | */ |
| | | @NotBlank(message = "ä»»å¡IDä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * å ç¾äººåid |
| | | */ |
| | | @NotEmpty(message = "å ç¾äººåä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<Long> assignees; |
| | | |
| | | /** |
| | | * å ç¾äººååç§° |
| | | */ |
| | | @NotEmpty(message = "å ç¾äººåä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<String> assigneeNames; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 驳ååæ°è¯·æ± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class BackProcessBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ID |
| | | */ |
| | | @NotBlank(message = "ä»»å¡IDä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»å |
| | | */ |
| | | private List<String> messageType; |
| | | |
| | | /** |
| | | * 驳åçèç¹id(ç®åæªä½¿ç¨ï¼ç´æ¥é©³åå°ç³è¯·äºº) |
| | | */ |
| | | @NotBlank(message = "驳åçèç¹ä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private String targetActivityId; |
| | | |
| | | /** |
| | | * åçæè§ |
| | | */ |
| | | private String message; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.workflow.domain.vo.WfCopy; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * åçä»»å¡è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class CompleteTaskBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | @NotBlank(message = "ä»»å¡idä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * éä»¶id |
| | | */ |
| | | private String fileId; |
| | | |
| | | /** |
| | | * æé人å |
| | | */ |
| | | private List<WfCopy> wfCopyList; |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»å |
| | | */ |
| | | private List<String> messageType; |
| | | |
| | | /** |
| | | * åçæè§ |
| | | */ |
| | | private String message; |
| | | |
| | | /** |
| | | * æµç¨åé |
| | | */ |
| | | private Map<String, Object> variables; |
| | | |
| | | public Map<String, Object> getVariables() { |
| | | if (variables == null) { |
| | | return new HashMap<>(16); |
| | | } |
| | | variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); |
| | | return variables; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class DelegateBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * å§æ´¾äººid |
| | | */ |
| | | @NotBlank(message = "å§æ´¾äººidä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String userId; |
| | | |
| | | /** |
| | | * å§æ´¾äººåç§° |
| | | */ |
| | | @NotBlank(message = "å§æ´¾äººåç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String nickName; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | @NotBlank(message = "ä»»å¡idä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String taskId; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åç¾åæ°è¯·æ± |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class DeleteMultiBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡ID |
| | | */ |
| | | @NotBlank(message = "ä»»å¡IDä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * åç¾äººå |
| | | */ |
| | | @NotEmpty(message = "åç¾äººåä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<String> taskIds; |
| | | |
| | | /** |
| | | * æ§è¡id |
| | | */ |
| | | @NotEmpty(message = "æ§è¡idä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<String> executionIds; |
| | | |
| | | /** |
| | | * 人åid |
| | | */ |
| | | @NotEmpty(message = "åç¾äººåidä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<Long> assigneeIds; |
| | | |
| | | /** |
| | | * 人ååç§° |
| | | */ |
| | | @NotEmpty(message = "åç¾äººåä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private List<String> assigneeNames; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.Pattern; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.workflow.common.constant.FlowConstant; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 模å请æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ModelBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 模åid |
| | | */ |
| | | @NotBlank(message = "模åIDä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private String id; |
| | | |
| | | /** |
| | | * 模ååç§° |
| | | */ |
| | | @NotBlank(message = "模ååç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String name; |
| | | |
| | | /** |
| | | * æ¨¡åæ è¯key |
| | | */ |
| | | @NotBlank(message = "æ¨¡åæ è¯keyä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | @Pattern(regexp = FlowConstant.MODEL_KEY_PATTERN, message = "æ¨¡åæ è¯keyåªè½å符æè
ä¸å线å¼å¤´", groups = {AddGroup.class}) |
| | | private String key; |
| | | |
| | | /** |
| | | * 模ååç±» |
| | | */ |
| | | @NotBlank(message = "模ååç±»ä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String categoryCode; |
| | | |
| | | /** |
| | | * 模åXML |
| | | */ |
| | | @NotBlank(message = "模åXMLä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String xml; |
| | | |
| | | /** |
| | | * 模åSVGå¾ç |
| | | */ |
| | | @NotBlank(message = "模åSVGä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private String svg; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String description; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ProcessDefinitionBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§°key |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * 模ååç±» |
| | | */ |
| | | private String categoryCode; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ProcessInstanceBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * æµç¨key |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * ä»»å¡å起人 |
| | | */ |
| | | private String startUserId; |
| | | |
| | | /** |
| | | * ä¸å¡id |
| | | */ |
| | | private String businessKey; |
| | | |
| | | /** |
| | | * 模ååç±» |
| | | */ |
| | | private String categoryCode; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ä½åºè¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ProcessInvalidBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | @NotBlank(message = "æµç¨å®ä¾idä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * ä½åºåå |
| | | */ |
| | | private String deleteReason; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * å¯å¨æµç¨å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class StartProcessBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸å¡å¯ä¸å¼id |
| | | */ |
| | | @NotBlank(message = "ä¸å¡IDä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String businessKey; |
| | | |
| | | /** |
| | | * 表å |
| | | */ |
| | | @NotBlank(message = "表åä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String tableName; |
| | | |
| | | /** |
| | | * æµç¨åéï¼åç«¯ä¼æäº¤ä¸ä¸ªå
ç´ {'entity': {ä¸å¡è¯¦æ
æ°æ®å¯¹è±¡}} |
| | | */ |
| | | private Map<String, Object> variables; |
| | | |
| | | public Map<String, Object> getVariables() { |
| | | if (variables == null) { |
| | | return new HashMap<>(16); |
| | | } |
| | | variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); |
| | | return variables; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | /** |
| | | * ç¨æ·å ç¾æ¥è¯¢ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class SysUserMultiBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 人ååç§° |
| | | */ |
| | | private String userName; |
| | | |
| | | /** |
| | | * 人ååç§° |
| | | */ |
| | | private String nickName; |
| | | |
| | | /** |
| | | * é¨é¨id |
| | | */ |
| | | private String deptId; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | private String taskId; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ä»»å¡è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class TaskBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String processDefinitionName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹key |
| | | */ |
| | | private String processDefinitionKey; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ä»»å¡å¬å |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class TaskUrgingBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»å |
| | | */ |
| | | private List<String> messageType; |
| | | |
| | | /** |
| | | * å¬åå
容ï¼ä¸ºç©ºé»è®¤ç³»ç»å
置信æ¯ï¼ |
| | | */ |
| | | private String message; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç»æ¢ä»»å¡è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class TerminationBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | @NotBlank(message = "ä»»å¡id为空", groups = AddGroup.class) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * å®¡æ¹æè§ |
| | | */ |
| | | private String comment; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.workflow.domain.TestLeave; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 请åä¸å¡å¯¹è±¡ test_leave |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = TestLeave.class, reverseConvertGenerate = false) |
| | | public class TestLeaveBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 请åç±»å |
| | | */ |
| | | @NotBlank(message = "请åç±»åä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String leaveType; |
| | | |
| | | /** |
| | | * å¼å§æ¶é´ |
| | | */ |
| | | @NotNull(message = "å¼å§æ¶é´ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | private Date startDate; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | @NotNull(message = "ç»ææ¶é´ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | private Date endDate; |
| | | |
| | | /** |
| | | * 请åå¤©æ° |
| | | */ |
| | | @NotNull(message = "请å天æ°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Integer leaveDays; |
| | | |
| | | /** |
| | | * å¼å§æ¶é´ |
| | | */ |
| | | private Integer startLeaveDays; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | private Integer endLeaveDays; |
| | | |
| | | /** |
| | | * 请ååå |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç»è½¬åå¡è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class TransmitBo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | @NotBlank(message = "ä»»å¡id为空", groups = AddGroup.class) |
| | | private String taskId; |
| | | |
| | | /** |
| | | * 转å人id |
| | | */ |
| | | @NotBlank(message = "转å人ä¸è½ä¸ºç©º", groups = AddGroup.class) |
| | | private String userId; |
| | | |
| | | /** |
| | | * å®¡æ¹æè§ |
| | | */ |
| | | private String comment; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | |
| | | /** |
| | | * æµç¨åç±»ä¸å¡å¯¹è±¡ wf_category |
| | | * |
| | | * @author may |
| | | * @date 2023-06-27 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = WfCategory.class, reverseConvertGenerate = false) |
| | | public class WfCategoryBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | */ |
| | | @NotBlank(message = "åç±»åç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String categoryName; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @NotBlank(message = "åç±»ç¼ç ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String categoryCode; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | | */ |
| | | @NotNull(message = "ç¶çº§idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | private Long sortNum; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import org.dromara.workflow.domain.WfDefinitionConfig; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import jakarta.validation.constraints.*; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½®ä¸å¡å¯¹è±¡ wf_form_definition |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = WfDefinitionConfig.class, reverseConvertGenerate = false) |
| | | public class WfDefinitionConfigBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表å |
| | | */ |
| | | @NotBlank(message = "表åä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String tableName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ID |
| | | */ |
| | | @NotBlank(message = "æµç¨å®ä¹IDä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æµç¨KEY |
| | | */ |
| | | @NotBlank(message = "æµç¨KEYä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private String processKey; |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @NotNull(message = "æµç¨çæ¬ä¸è½ä¸ºç©º", groups = {AddGroup.class}) |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import org.dromara.workflow.domain.WfFormManage; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import jakarta.validation.constraints.*; |
| | | |
| | | /** |
| | | * 表å管çä¸å¡å¯¹è±¡ wf_form_manage |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = WfFormManage.class, reverseConvertGenerate = false) |
| | | public class WfFormManageBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = { EditGroup.class }) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @NotBlank(message = "表ååç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | @NotBlank(message = "表åç±»åä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String formType; |
| | | /** |
| | | * è·¯ç±å°å/表åID |
| | | */ |
| | | @NotBlank(message = "è·¯ç±å°å/表åIDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String router; |
| | | |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.bo; |
| | | |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import jakarta.validation.constraints.*; |
| | | |
| | | /** |
| | | * èç¹é
ç½®ä¸å¡å¯¹è±¡ wf_node_config |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = WfNodeConfig.class, reverseConvertGenerate = false) |
| | | public class WfNodeConfigBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表åid |
| | | */ |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | private String formType; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | @NotBlank(message = "èç¹åç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | @NotBlank(message = "èç¹idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String nodeId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | @NotBlank(message = "æµç¨å®ä¹idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç³è¯·äººèç¹ ï¼0æ¯ 1å¦ï¼ |
| | | */ |
| | | @NotBlank(message = "æ¯å¦ä¸ºç³è¯·äººèç¹ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) |
| | | private String applyUserTask; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | import org.dromara.common.translation.annotation.Translation; |
| | | import org.dromara.common.translation.constant.TransConstant; |
| | | import org.flowable.engine.task.Attachment; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®¡æ¹è®°å½è§å¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ActHistoryInfoVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | private String id; |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | private String taskDefinitionKey; |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | private String name; |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | private String processInstanceId; |
| | | /** |
| | | * å¼å§æ¶é´ |
| | | */ |
| | | private Date startTime; |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | private Date endTime; |
| | | /** |
| | | * è¿è¡æ¶é¿ |
| | | */ |
| | | private String runDuration; |
| | | /** |
| | | * ç¶æ |
| | | */ |
| | | private String status; |
| | | /** |
| | | * ç¶æ |
| | | */ |
| | | private String statusName; |
| | | /** |
| | | * åç人id |
| | | */ |
| | | private String assignee; |
| | | |
| | | /** |
| | | * åç人åç§° |
| | | */ |
| | | @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "assignee") |
| | | private String nickName; |
| | | |
| | | /** |
| | | * åç人id |
| | | */ |
| | | private String owner; |
| | | |
| | | /** |
| | | * 审æ¹ä¿¡æ¯id |
| | | */ |
| | | private String commentId; |
| | | |
| | | /** |
| | | * 审æ¹ä¿¡æ¯ |
| | | */ |
| | | private String comment; |
| | | |
| | | /** |
| | | * 审æ¹éä»¶ |
| | | */ |
| | | private List<Attachment> attachmentList; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * èç¹å¾å½¢ä¿¡æ¯ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class GraphicInfoVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | /** |
| | | * xåæ |
| | | */ |
| | | private double x; |
| | | |
| | | /** |
| | | * yåæ |
| | | */ |
| | | private double y; |
| | | |
| | | /** |
| | | * èç¹é«åº¦ |
| | | */ |
| | | private double height; |
| | | |
| | | /** |
| | | * èç¹å®½åº¦ |
| | | */ |
| | | private double width; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | private String nodeId; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String nodeName; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 模åè§å¾å¯¹è±¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ModelVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 模åid |
| | | */ |
| | | private String id; |
| | | |
| | | /** |
| | | * 模ååç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * æ¨¡åæ è¯key |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * 模ååç±» |
| | | */ |
| | | private String categoryCode; |
| | | |
| | | /** |
| | | * 模åXML |
| | | */ |
| | | private String xml; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String description; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * å¤å®ä¾ä¿¡æ¯ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class MultiInstanceVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¼ç¾ç±»åï¼ä¸²è¡ï¼å¹¶è¡ï¼ |
| | | */ |
| | | private Object type; |
| | | |
| | | /** |
| | | * ä¼ç¾äººåKEY |
| | | */ |
| | | private String assignee; |
| | | |
| | | /** |
| | | * ä¼ç¾äººåéåKEY |
| | | */ |
| | | private String assigneeList; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åä¸è
|
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ParticipantVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç»idï¼è§è²idï¼ |
| | | */ |
| | | private List<Long> groupIds; |
| | | |
| | | /** |
| | | * åé人idï¼ç¨æ·idï¼ å½ç»idä¸ä¸ºç©ºæ¶ï¼å°ç»å
äººåæ¥åºæ¾å
¥candidate |
| | | */ |
| | | private List<Long> candidate; |
| | | |
| | | /** |
| | | * åé人åç§°ï¼ç¨æ·åç§°ï¼ å½ç»idä¸ä¸ºç©ºæ¶ï¼å°ç»å
äººåæ¥åºæ¾å
¥candidateName |
| | | */ |
| | | private List<String> candidateName; |
| | | |
| | | /** |
| | | * æ¯å¦è®¤é¢æ è¯ |
| | | * å½ä¸ºç©ºæ¶é»è®¤å½åä»»å¡ä¸éè¦è®¤é¢ |
| | | * å½ä¸ºtrueæ¶å½åä»»å¡è¯´æä¸ºå鿍¡å¼å¹¶ä¸æäººå·²ç»è®¤é¢äºä»»å¡å¯ä»¥å½è¿ï¼ |
| | | * å½ä¸ºfalseæ¶å½åä»»å¡è¯´æä¸ºå鿍¡å¼è¯¥ä»»å¡æªè®¤é¢ï¼ |
| | | */ |
| | | private Boolean claim; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è§å¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ProcessDefinitionVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | private String id; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹æ è¯key |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹çæ¬ |
| | | */ |
| | | private int version; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹æèµ·ææ¿æ´» 1æ¿æ´» 2æèµ· |
| | | */ |
| | | private int suspensionState; |
| | | |
| | | /** |
| | | * æµç¨xmlåç§° |
| | | */ |
| | | private String resourceName; |
| | | |
| | | /** |
| | | * æµç¨å¾çåç§° |
| | | */ |
| | | private String diagramResourceName; |
| | | |
| | | /** |
| | | * æµç¨é¨ç½²id |
| | | */ |
| | | private String deploymentId; |
| | | |
| | | /** |
| | | * æµç¨é¨ç½²æ¶é´ |
| | | */ |
| | | private Date deploymentTime; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½® |
| | | */ |
| | | private WfDefinitionConfigVo wfDefinitionConfigVo; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾è§å¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class ProcessInstanceVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | private String id; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | private String processDefinitionId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String processDefinitionName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹key |
| | | */ |
| | | private String processDefinitionKey; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹çæ¬ |
| | | */ |
| | | private Integer processDefinitionVersion; |
| | | |
| | | /** |
| | | * é¨ç½²id |
| | | */ |
| | | private String deploymentId; |
| | | |
| | | /** |
| | | * ä¸å¡id |
| | | */ |
| | | private String businessKey; |
| | | |
| | | /** |
| | | * æ¯å¦æèµ· |
| | | */ |
| | | private Boolean isSuspended; |
| | | |
| | | /** |
| | | * ç§æ·id |
| | | */ |
| | | private String tenantId; |
| | | |
| | | /** |
| | | * å¯å¨æ¶é´ |
| | | */ |
| | | private Date startTime; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | private Date endTime; |
| | | |
| | | /** |
| | | * å¯å¨äººid |
| | | */ |
| | | private String startUserId; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | private String businessStatus; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | private String businessStatusName; |
| | | |
| | | /** |
| | | * å¾
åä»»å¡éå |
| | | */ |
| | | private List<TaskVo> taskVoList; |
| | | |
| | | /** |
| | | * èç¹é
ç½® |
| | | */ |
| | | private WfNodeConfigVo wfNodeConfigVo; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | import org.dromara.common.translation.annotation.Translation; |
| | | import org.dromara.common.translation.constant.TransConstant; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * ä»»å¡è§å¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class TaskVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä»»å¡id |
| | | */ |
| | | private String id; |
| | | |
| | | /** |
| | | * ä»»å¡åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private String description; |
| | | |
| | | /** |
| | | * ä¼å
级 |
| | | */ |
| | | private Integer priority; |
| | | |
| | | /** |
| | | * è´è´£æ¤ä»»å¡ç人åçç¨æ·id |
| | | */ |
| | | private String owner; |
| | | |
| | | /** |
| | | * åç人id |
| | | */ |
| | | private Long assignee; |
| | | |
| | | /** |
| | | * åç人 |
| | | */ |
| | | @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "assignee") |
| | | private String assigneeName; |
| | | |
| | | |
| | | /** |
| | | * æµç¨å®ä¾id |
| | | */ |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * æ§è¡id |
| | | */ |
| | | private String executionId; |
| | | |
| | | /** |
| | | * æ ç¨ |
| | | */ |
| | | private String taskDefinitionId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | private String processDefinitionId; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * å·²åä»»å¡-å建æ¶é´ |
| | | */ |
| | | private Date startTime; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | private Date endTime; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | private String taskDefinitionKey; |
| | | |
| | | /** |
| | | * 任塿ªæ¢æ¥æ |
| | | */ |
| | | private Date dueDate; |
| | | |
| | | /** |
| | | * æµç¨ç±»å« |
| | | */ |
| | | private String category; |
| | | |
| | | /** |
| | | * ç¶çº§ä»»å¡id |
| | | */ |
| | | private String parentTaskId; |
| | | |
| | | /** |
| | | * ç§æ·id |
| | | */ |
| | | private String tenantId; |
| | | |
| | | /** |
| | | * è®¤é¢æ¶é´ |
| | | */ |
| | | private Date claimTime; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | private String businessStatus; |
| | | |
| | | /** |
| | | * æµç¨ç¶æ |
| | | */ |
| | | private String businessStatusName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹åç§° |
| | | */ |
| | | private String processDefinitionName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹key |
| | | */ |
| | | private String processDefinitionKey; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹çæ¬ |
| | | */ |
| | | private Integer processDefinitionVersion; |
| | | |
| | | /** |
| | | * åä¸è
|
| | | */ |
| | | private ParticipantVo participantVo; |
| | | |
| | | /** |
| | | * æ¯å¦ä¼ç¾ |
| | | */ |
| | | private Boolean multiInstance; |
| | | |
| | | /** |
| | | * ä¸å¡id |
| | | */ |
| | | private String businessKey; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½® |
| | | */ |
| | | private WfDefinitionConfigVo wfDefinitionConfigVo; |
| | | |
| | | /** |
| | | * èç¹é
ç½® |
| | | */ |
| | | private WfNodeConfigVo wfNodeConfigVo; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.dromara.workflow.domain.TestLeave; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * 请åè§å¾å¯¹è±¡ test_leave |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = TestLeave.class) |
| | | public class TestLeaveVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "主é®") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 请åç±»å |
| | | */ |
| | | @ExcelProperty(value = "请åç±»å") |
| | | private String leaveType; |
| | | |
| | | /** |
| | | * å¼å§æ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "å¼å§æ¶é´") |
| | | private Date startDate; |
| | | |
| | | /** |
| | | * ç»ææ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "ç»ææ¶é´") |
| | | private Date endDate; |
| | | |
| | | /** |
| | | * 请åå¤©æ° |
| | | */ |
| | | @ExcelProperty(value = "请å天æ°") |
| | | private Integer leaveDays; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "请ååå ") |
| | | private String remark; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾å¯¹è±¡ |
| | | */ |
| | | private ProcessInstanceVo processInstanceVo; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æµç¨åé |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class VariableVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * åékey |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * åéå¼ |
| | | */ |
| | | private String value; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | /** |
| | | * æµç¨åç±»è§å¾å¯¹è±¡ wf_category |
| | | * |
| | | * @author may |
| | | * @date 2023-06-27 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = WfCategory.class) |
| | | public class WfCategoryVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "主é®") |
| | | private Long id; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | */ |
| | | @ExcelProperty(value = "åç±»åç§°") |
| | | private String categoryName; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "åç±»ç¼ç ") |
| | | private String categoryCode; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | | */ |
| | | @ExcelProperty(value = "ç¶çº§id") |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | @ExcelProperty(value = "æåº") |
| | | private Long sortNum; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æé |
| | | * |
| | | * @author may |
| | | */ |
| | | @Data |
| | | public class WfCopy implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¨æ·id |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * ç¨æ·åç§° |
| | | */ |
| | | private String userName; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import org.dromara.workflow.domain.WfDefinitionConfig; |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½®è§å¾å¯¹è±¡ wf_definition_config |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = WfDefinitionConfig.class) |
| | | public class WfDefinitionConfigVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "主é®") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表å |
| | | */ |
| | | @ExcelProperty(value = "表å") |
| | | private String tableName; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ID |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¹ID") |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æµç¨KEY |
| | | */ |
| | | @ExcelProperty(value = "æµç¨KEY") |
| | | private String processKey; |
| | | |
| | | |
| | | /** |
| | | * æµç¨çæ¬ |
| | | */ |
| | | @ExcelProperty(value = "æµç¨çæ¬") |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "夿³¨") |
| | | private String remark; |
| | | |
| | | /** |
| | | * 表å管ç |
| | | */ |
| | | private WfFormManageVo wfFormManageVo; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import org.dromara.workflow.domain.WfFormManage; |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | /** |
| | | * 表å管çè§å¾å¯¹è±¡ wf_form_manage |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = WfFormManage.class) |
| | | public class WfFormManageVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "主é®") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表ååç§° |
| | | */ |
| | | @ExcelProperty(value = "表ååç§°") |
| | | private String formName; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | @ExcelProperty(value = "表åç±»å") |
| | | private String formType; |
| | | |
| | | /** |
| | | * 表åç±»ååç§° |
| | | */ |
| | | private String formTypeName; |
| | | |
| | | /** |
| | | * è·¯ç±å°å/表åID |
| | | */ |
| | | @ExcelProperty(value = "è·¯ç±å°å/表åID") |
| | | private String router; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "夿³¨") |
| | | private String remark; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.domain.vo; |
| | | |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | /** |
| | | * èç¹é
ç½®è§å¾å¯¹è±¡ wf_node_config |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = WfNodeConfig.class) |
| | | public class WfNodeConfigVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | @ExcelProperty(value = "主é®") |
| | | private Long id; |
| | | |
| | | /** |
| | | * 表åid |
| | | */ |
| | | @ExcelProperty(value = "表åid") |
| | | private Long formId; |
| | | |
| | | /** |
| | | * 表åç±»å |
| | | */ |
| | | @ExcelProperty(value = "表åç±»å") |
| | | private String formType; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | @ExcelProperty(value = "èç¹åç§°") |
| | | private String nodeName; |
| | | |
| | | /** |
| | | * èç¹id |
| | | */ |
| | | @ExcelProperty(value = "èç¹id") |
| | | private String nodeId; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹id |
| | | */ |
| | | @ExcelProperty(value = "æµç¨å®ä¹id") |
| | | private String definitionId; |
| | | |
| | | /** |
| | | * æ¯å¦ä¸ºç³è¯·äººèç¹ ï¼0æ¯ 1å¦ï¼ |
| | | */ |
| | | @ExcelProperty(value = "æ¯å¦ä¸ºç³è¯·äººèç¹ ï¼0æ¯ 1å¦ï¼") |
| | | private String applyUserTask; |
| | | |
| | | /** |
| | | * 表å管ç |
| | | */ |
| | | private WfFormManageVo wfFormManageVo; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable; |
| | | |
| | | 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; |
| | | |
| | | public class CustomDefaultProcessDiagramCanvas extends DefaultProcessDiagramCanvas { |
| | | //设置é«äº®çº¿çé¢è² è¿éæè®¾ç½®æç»¿è² |
| | | protected static Color HIGHLIGHT_SEQUENCEFLOW_COLOR = Color.GREEN; |
| | | |
| | | public CustomDefaultProcessDiagramCanvas(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 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(HIGHLIGHT_SEQUENCEFLOW_COLOR); |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | | * é«äº®èç¹è®¾ç½® |
| | | */ |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | | * @description: é«äº®èç¹çº¢è² |
| | | * @param: x |
| | | * @param: y |
| | | * @param: width |
| | | * @param: height |
| | | * @return: void |
| | | * @author: gssong |
| | | * @date: 2022/4/12 |
| | | */ |
| | | public void drawHighLightRed(int x, int y, int width, int height) { |
| | | Paint originalPaint = g.getPaint(); |
| | | Stroke originalStroke = g.getStroke(); |
| | | //设置é«äº®èç¹çé¢è² |
| | | g.setPaint(Color.green); |
| | | 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); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* Licensed under the Apache License, Version 2.0 (the "License"); |
| | | * you may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at |
| | | * |
| | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | */ |
| | | |
| | | package org.dromara.workflow.flowable; |
| | | |
| | | import org.flowable.bpmn.model.Event; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.image.ProcessDiagramGenerator; |
| | | |
| | | import java.awt.*; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * Class to generate an image based the diagram interchange information in a BPMN 2.0 process. |
| | | * |
| | | * @author Joram Barrez |
| | | * @author Tijs Rademakers |
| | | * @author Zheng Ji |
| | | */ |
| | | public class CustomDefaultProcessDiagramGenerator implements ProcessDiagramGenerator { |
| | | |
| | | protected Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions = new HashMap<>(); |
| | | protected Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap<>(); |
| | | |
| | | public CustomDefaultProcessDiagramGenerator() { |
| | | this(1.0); |
| | | } |
| | | |
| | | // The instructions on how to draw a certain construct is |
| | | // created statically and stored in a map for performance. |
| | | public CustomDefaultProcessDiagramGenerator(final double scaleFactor) { |
| | | // start event |
| | | activityDrawInstructions.put(StartEvent.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | StartEvent startEvent = (StartEvent) flowNode; |
| | | if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) { |
| | | EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0); |
| | | if (eventDefinition instanceof TimerEventDefinition) { |
| | | processDiagramCanvas.drawTimerStartEvent(graphicInfo, scaleFactor); |
| | | } else if (eventDefinition instanceof ErrorEventDefinition) { |
| | | processDiagramCanvas.drawErrorStartEvent(graphicInfo, scaleFactor); |
| | | } else if (eventDefinition instanceof EscalationEventDefinition) { |
| | | processDiagramCanvas.drawEscalationStartEvent(graphicInfo, scaleFactor); |
| | | } else if (eventDefinition instanceof ConditionalEventDefinition) { |
| | | processDiagramCanvas.drawConditionalStartEvent(graphicInfo, scaleFactor); |
| | | } else if (eventDefinition instanceof SignalEventDefinition) { |
| | | processDiagramCanvas.drawSignalStartEvent(graphicInfo, scaleFactor); |
| | | } else if (eventDefinition instanceof MessageEventDefinition) { |
| | | processDiagramCanvas.drawMessageStartEvent(graphicInfo, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawNoneStartEvent(graphicInfo); |
| | | } |
| | | } else { |
| | | List<ExtensionElement> eventTypeElements = startEvent.getExtensionElements().get("eventType"); |
| | | if (eventTypeElements != null && eventTypeElements.size() > 0) { |
| | | processDiagramCanvas.drawEventRegistryStartEvent(graphicInfo, scaleFactor); |
| | | |
| | | } else { |
| | | processDiagramCanvas.drawNoneStartEvent(graphicInfo); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // signal catch |
| | | activityDrawInstructions.put(IntermediateCatchEvent.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode; |
| | | if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent.getEventDefinitions().isEmpty()) { |
| | | |
| | | if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) { |
| | | processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) { |
| | | processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) { |
| | | processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof ConditionalEventDefinition) { |
| | | processDiagramCanvas.drawCatchingConditionalEvent(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // signal throw |
| | | activityDrawInstructions.put(ThrowEvent.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | ThrowEvent throwEvent = (ThrowEvent) flowNode; |
| | | if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) { |
| | | if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) { |
| | | processDiagramCanvas.drawThrowingSignalEvent(graphicInfo, scaleFactor); |
| | | } else if (throwEvent.getEventDefinitions().get(0) instanceof EscalationEventDefinition) { |
| | | processDiagramCanvas.drawThrowingEscalationEvent(graphicInfo, scaleFactor); |
| | | } else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) { |
| | | processDiagramCanvas.drawThrowingCompensateEvent(graphicInfo, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor); |
| | | } |
| | | } else { |
| | | processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // end event |
| | | activityDrawInstructions.put(EndEvent.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | EndEvent endEvent = (EndEvent) flowNode; |
| | | if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) { |
| | | if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) { |
| | | processDiagramCanvas.drawErrorEndEvent(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } else if (endEvent.getEventDefinitions().get(0) instanceof EscalationEventDefinition) { |
| | | processDiagramCanvas.drawEscalationEndEvent(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor); |
| | | } |
| | | } else { |
| | | processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // task |
| | | activityDrawInstructions.put(Task.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // user task |
| | | activityDrawInstructions.put(UserTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawUserTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // script task |
| | | activityDrawInstructions.put(ScriptTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawScriptTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // service task |
| | | activityDrawInstructions.put(ServiceTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | ServiceTask serviceTask = (ServiceTask) flowNode; |
| | | if ("camel".equalsIgnoreCase(serviceTask.getType())) { |
| | | processDiagramCanvas.drawCamelTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | }else if (ServiceTask.HTTP_TASK.equalsIgnoreCase(serviceTask.getType())) { |
| | | processDiagramCanvas.drawHttpTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | } else if (ServiceTask.DMN_TASK.equalsIgnoreCase(serviceTask.getType())) { |
| | | processDiagramCanvas.drawDMNTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | } else if (ServiceTask.SHELL_TASK.equalsIgnoreCase(serviceTask.getType())) { |
| | | processDiagramCanvas.drawShellTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawServiceTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // http service task |
| | | activityDrawInstructions.put(HttpServiceTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawHttpTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // receive task |
| | | activityDrawInstructions.put(ReceiveTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawReceiveTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // send task |
| | | activityDrawInstructions.put(SendTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawSendTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // manual task |
| | | activityDrawInstructions.put(ManualTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawManualTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // send event service task |
| | | activityDrawInstructions.put(SendEventServiceTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawSendEventServiceTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // external worker service task |
| | | activityDrawInstructions.put(ExternalWorkerServiceTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | ServiceTask serviceTask = (ServiceTask) flowNode; |
| | | processDiagramCanvas.drawServiceTask(serviceTask.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // case service task |
| | | activityDrawInstructions.put(CaseServiceTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawCaseServiceTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // businessRuleTask task |
| | | activityDrawInstructions.put(BusinessRuleTask.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawBusinessRuleTask(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // exclusive gateway |
| | | activityDrawInstructions.put(ExclusiveGateway.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawExclusiveGateway(graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // inclusive gateway |
| | | activityDrawInstructions.put(InclusiveGateway.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawInclusiveGateway(graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // parallel gateway |
| | | activityDrawInstructions.put(ParallelGateway.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawParallelGateway(graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // event based gateway |
| | | activityDrawInstructions.put(EventGateway.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawEventBasedGateway(graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // Boundary timer |
| | | activityDrawInstructions.put(BoundaryEvent.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode; |
| | | if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) { |
| | | EventDefinition eventDefinition = boundaryEvent.getEventDefinitions().get(0); |
| | | if (eventDefinition instanceof TimerEventDefinition) { |
| | | processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof ConditionalEventDefinition) { |
| | | processDiagramCanvas.drawCatchingConditionalEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof ErrorEventDefinition) { |
| | | processDiagramCanvas.drawCatchingErrorEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof EscalationEventDefinition) { |
| | | processDiagramCanvas.drawCatchingEscalationEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof SignalEventDefinition) { |
| | | processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof MessageEventDefinition) { |
| | | processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | |
| | | } else if (eventDefinition instanceof CompensateEventDefinition) { |
| | | processDiagramCanvas.drawCatchingCompensateEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | } |
| | | |
| | | } else { |
| | | List<ExtensionElement> eventTypeElements = boundaryEvent.getExtensionElements().get("eventType"); |
| | | if (eventTypeElements != null && eventTypeElements.size() > 0) { |
| | | processDiagramCanvas.drawCatchingEventRegistryEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // subprocess |
| | | activityDrawInstructions.put(SubProcess.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // transaction |
| | | activityDrawInstructions.put(Transaction.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawExpandedTransaction(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // Event subprocess |
| | | activityDrawInstructions.put(EventSubProcess.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, true, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // Adhoc subprocess |
| | | activityDrawInstructions.put(AdhocSubProcess.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); |
| | | } else { |
| | | processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // call activity |
| | | activityDrawInstructions.put(CallActivity.class, new ActivityDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | processDiagramCanvas.drawCollapsedCallActivity(flowNode.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // text annotation |
| | | artifactDrawInstructions.put(TextAnnotation.class, new ArtifactDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId()); |
| | | TextAnnotation textAnnotation = (TextAnnotation) artifact; |
| | | processDiagramCanvas.drawTextAnnotation(textAnnotation.getText(), graphicInfo, scaleFactor); |
| | | } |
| | | }); |
| | | |
| | | // association |
| | | artifactDrawInstructions.put(Association.class, new ArtifactDrawInstruction() { |
| | | |
| | | @Override |
| | | public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) { |
| | | Association association = (Association) artifact; |
| | | String sourceRef = association.getSourceRef(); |
| | | String targetRef = association.getTargetRef(); |
| | | |
| | | // source and target can be instance of FlowElement or Artifact |
| | | BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef); |
| | | BaseElement targetElement = bpmnModel.getFlowElement(targetRef); |
| | | if (sourceElement == null) { |
| | | sourceElement = bpmnModel.getArtifact(sourceRef); |
| | | } |
| | | if (targetElement == null) { |
| | | targetElement = bpmnModel.getArtifact(targetRef); |
| | | } |
| | | List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId()); |
| | | 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(); |
| | | } |
| | | |
| | | AssociationDirection associationDirection = association.getAssociationDirection(); |
| | | processDiagramCanvas.drawAssociation(xPoints, yPoints, associationDirection, false, scaleFactor); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows, |
| | | String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, |
| | | activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI).generateImage(imageType); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, 1.0, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, |
| | | List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, |
| | | String labelFontName, String annotationFontName, ClassLoader customClassLoader, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), |
| | | activityFontName, labelFontName, annotationFontName, customClassLoader, 1.0, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, |
| | | String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), |
| | | activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generatePngDiagram(BpmnModel bpmnModel, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generatePngDiagram(bpmnModel, 1.0, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generatePngDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateJpgDiagram(BpmnModel bpmnModel) { |
| | | return generateJpgDiagram(bpmnModel, 1.0, false); |
| | | } |
| | | |
| | | @Override |
| | | public InputStream generateJpgDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | return generateDiagram(bpmnModel, "jpg", Collections.emptyList(), Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | public BufferedImage generateImage(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows, |
| | | String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, |
| | | activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI).generateBufferedImage(imageType); |
| | | } |
| | | |
| | | public BufferedImage generateImage(BpmnModel bpmnModel, String imageType, |
| | | List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | return generateImage(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | |
| | | @Override |
| | | public BufferedImage generatePngImage(BpmnModel bpmnModel, double scaleFactor) { |
| | | return generateImage(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), scaleFactor, false); |
| | | } |
| | | |
| | | protected CustomDefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, |
| | | List<String> highLightedActivities, List<String> highLightedFlows, |
| | | String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { |
| | | |
| | | prepareBpmnModel(bpmnModel); |
| | | |
| | | CustomDefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); |
| | | |
| | | // Draw pool shape, if process is participant in collaboration |
| | | for (Pool pool : bpmnModel.getPools()) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId()); |
| | | processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | |
| | | // Draw lanes |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | for (Lane lane : process.getLanes()) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId()); |
| | | processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo, scaleFactor); |
| | | } |
| | | } |
| | | |
| | | // Draw activities and their sequence-flows |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) { |
| | | if (!isPartOfCollapsedSubProcess(flowNode, bpmnModel)) { |
| | | drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, drawSequenceFlowNameWithNoLabelDI); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Draw artifacts |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | |
| | | for (Artifact artifact : process.getArtifacts()) { |
| | | drawArtifact(processDiagramCanvas, bpmnModel, artifact); |
| | | } |
| | | |
| | | List<SubProcess> subProcesses = process.findFlowElementsOfType(SubProcess.class, true); |
| | | if (subProcesses != null) { |
| | | for (SubProcess subProcess : subProcesses) { |
| | | |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(subProcess.getId()); |
| | | if (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | continue; |
| | | } |
| | | |
| | | if (!isPartOfCollapsedSubProcess(subProcess, bpmnModel)) { |
| | | for (Artifact subProcessArtifact : subProcess.getArtifacts()) { |
| | | drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return processDiagramCanvas; |
| | | } |
| | | |
| | | protected void prepareBpmnModel(BpmnModel bpmnModel) { |
| | | |
| | | // Need to make sure all elements have positive x and y. |
| | | // Check all graphicInfo and update the elements accordingly |
| | | |
| | | List<GraphicInfo> allGraphicInfos = new ArrayList<>(); |
| | | if (bpmnModel.getLocationMap() != null) { |
| | | allGraphicInfos.addAll(bpmnModel.getLocationMap().values()); |
| | | } |
| | | if (bpmnModel.getLabelLocationMap() != null) { |
| | | allGraphicInfos.addAll(bpmnModel.getLabelLocationMap().values()); |
| | | } |
| | | if (bpmnModel.getFlowLocationMap() != null) { |
| | | for (List<GraphicInfo> flowGraphicInfos : bpmnModel.getFlowLocationMap().values()) { |
| | | allGraphicInfos.addAll(flowGraphicInfos); |
| | | } |
| | | } |
| | | |
| | | if (allGraphicInfos.size() > 0) { |
| | | |
| | | boolean needsTranslationX = false; |
| | | boolean needsTranslationY = false; |
| | | |
| | | double lowestX = 0.0; |
| | | double lowestY = 0.0; |
| | | |
| | | // Collect lowest x and y |
| | | for (GraphicInfo graphicInfo : allGraphicInfos) { |
| | | |
| | | double x = graphicInfo.getX(); |
| | | double y = graphicInfo.getY(); |
| | | |
| | | if (x < lowestX) { |
| | | needsTranslationX = true; |
| | | lowestX = x; |
| | | } |
| | | if (y < lowestY) { |
| | | needsTranslationY = true; |
| | | lowestY = y; |
| | | } |
| | | |
| | | } |
| | | |
| | | // Update all graphicInfo objects |
| | | if (needsTranslationX || needsTranslationY) { |
| | | |
| | | double translationX = Math.abs(lowestX); |
| | | double translationY = Math.abs(lowestY); |
| | | |
| | | for (GraphicInfo graphicInfo : allGraphicInfos) { |
| | | if (needsTranslationX) { |
| | | graphicInfo.setX(graphicInfo.getX() + translationX); |
| | | } |
| | | if (needsTranslationY) { |
| | | graphicInfo.setY(graphicInfo.getY() + translationY); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void drawActivity(CustomDefaultProcessDiagramCanvas 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())) { |
| | | drawHighLightRed(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); |
| | | } else if (highLightedActivities.contains(Color.RED.toString() + flowNode.getId())) { |
| | | drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); |
| | | } |
| | | |
| | | } else if (flowNode instanceof Task) { |
| | | activityDrawInstructions.get(Task.class).draw(processDiagramCanvas, bpmnModel, flowNode); |
| | | |
| | | if (highLightedActivities.contains(flowNode.getId())) { |
| | | drawHighLightRed(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); |
| | | } else if (highLightedActivities.contains(Color.RED.toString() + flowNode.getId())) { |
| | | 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 && sequenceFlow.getConditionExpression().trim().length() > 0 && !(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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * This method makes coordinates of connection flow better. |
| | | * |
| | | * @param processDiagramCanvas |
| | | * @param bpmnModel |
| | | * @param sourceElement |
| | | * @param targetElement |
| | | * @param graphicInfoList |
| | | * @return |
| | | */ |
| | | protected static List<GraphicInfo> connectionPerfectionizer(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, BaseElement sourceElement, BaseElement targetElement, List<GraphicInfo> graphicInfoList) { |
| | | GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId()); |
| | | GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId()); |
| | | |
| | | CustomDefaultProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement); |
| | | CustomDefaultProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement); |
| | | |
| | | return processDiagramCanvas.connectionPerfectionizer(sourceShapeType, targetShapeType, sourceGraphicInfo, targetGraphicInfo, graphicInfoList); |
| | | } |
| | | |
| | | /** |
| | | * This method returns shape type of base element.<br> |
| | | * Each element can be presented as rectangle, rhombus, or ellipse. |
| | | * |
| | | * @param baseElement |
| | | * @return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE |
| | | */ |
| | | protected static CustomDefaultProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) { |
| | | if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) { |
| | | return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Rectangle; |
| | | } else if (baseElement instanceof Gateway) { |
| | | return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Rhombus; |
| | | } else if (baseElement instanceof Event) { |
| | | return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Ellipse; |
| | | } else { |
| | | // unknown source element, just do not correct coordinates |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | protected static GraphicInfo getLineCenter(List<GraphicInfo> graphicInfoList) { |
| | | GraphicInfo gi = new GraphicInfo(); |
| | | |
| | | int[] xPoints = new int[graphicInfoList.size()]; |
| | | int[] yPoints = new int[graphicInfoList.size()]; |
| | | |
| | | double length = 0; |
| | | double[] lengths = new double[graphicInfoList.size()]; |
| | | lengths[0] = 0; |
| | | double m; |
| | | 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(); |
| | | |
| | | length += Math.sqrt( |
| | | Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(), 2) + |
| | | Math.pow((int) graphicInfo.getY() - (int) previousGraphicInfo.getY(), 2)); |
| | | lengths[i] = length; |
| | | } |
| | | m = length / 2; |
| | | int p1 = 0; |
| | | int p2 = 1; |
| | | for (int i = 1; i < lengths.length; i++) { |
| | | double len = lengths[i]; |
| | | p1 = i - 1; |
| | | p2 = i; |
| | | if (len > m) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | GraphicInfo graphicInfo1 = graphicInfoList.get(p1); |
| | | GraphicInfo graphicInfo2 = graphicInfoList.get(p2); |
| | | |
| | | double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX(); |
| | | double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY(); |
| | | double OB = lengths[p2] - lengths[p1]; |
| | | double ob = m - lengths[p1]; |
| | | double ab = AB * ob / OB; |
| | | double oa = OA * ob / OB; |
| | | |
| | | double mx = graphicInfo1.getX() + ab; |
| | | double my = graphicInfo1.getY() + oa; |
| | | |
| | | gi.setX(mx); |
| | | gi.setY(my); |
| | | return gi; |
| | | } |
| | | |
| | | protected void drawArtifact(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) { |
| | | |
| | | ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass()); |
| | | if (drawInstruction != null) { |
| | | drawInstruction.draw(processDiagramCanvas, bpmnModel, artifact); |
| | | } |
| | | } |
| | | |
| | | private static void drawHighLight(CustomDefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { |
| | | processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight()); |
| | | |
| | | } |
| | | |
| | | private static void drawHighLightRed(CustomDefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { |
| | | processDiagramCanvas.drawHighLightRed((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight()); |
| | | |
| | | } |
| | | |
| | | protected static CustomDefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType, |
| | | String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) { |
| | | |
| | | // We need to calculate maximum values to know how big the image will be in its entirety |
| | | double minX = Double.MAX_VALUE; |
| | | double maxX = 0; |
| | | double minY = Double.MAX_VALUE; |
| | | double maxY = 0; |
| | | |
| | | for (Pool pool : bpmnModel.getPools()) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId()); |
| | | minX = graphicInfo.getX(); |
| | | maxX = graphicInfo.getX() + graphicInfo.getWidth(); |
| | | minY = graphicInfo.getY(); |
| | | maxY = graphicInfo.getY() + graphicInfo.getHeight(); |
| | | } |
| | | |
| | | List<FlowNode> flowNodes = gatherAllFlowNodes(bpmnModel); |
| | | for (FlowNode flowNode : flowNodes) { |
| | | |
| | | GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); |
| | | |
| | | // width |
| | | if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) { |
| | | maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth(); |
| | | } |
| | | if (flowNodeGraphicInfo.getX() < minX) { |
| | | minX = flowNodeGraphicInfo.getX(); |
| | | } |
| | | // height |
| | | if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) { |
| | | maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight(); |
| | | } |
| | | if (flowNodeGraphicInfo.getY() < minY) { |
| | | minY = flowNodeGraphicInfo.getY(); |
| | | } |
| | | |
| | | for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) { |
| | | List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId()); |
| | | if (graphicInfoList != null) { |
| | | for (GraphicInfo graphicInfo : graphicInfoList) { |
| | | // width |
| | | if (graphicInfo.getX() > maxX) { |
| | | maxX = graphicInfo.getX(); |
| | | } |
| | | if (graphicInfo.getX() < minX) { |
| | | minX = graphicInfo.getX(); |
| | | } |
| | | // height |
| | | if (graphicInfo.getY() > maxY) { |
| | | maxY = graphicInfo.getY(); |
| | | } |
| | | if (graphicInfo.getY() < minY) { |
| | | minY = graphicInfo.getY(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | List<Artifact> artifacts = gatherAllArtifacts(bpmnModel); |
| | | for (Artifact artifact : artifacts) { |
| | | |
| | | GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId()); |
| | | |
| | | if (artifactGraphicInfo != null) { |
| | | // width |
| | | if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) { |
| | | maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth(); |
| | | } |
| | | if (artifactGraphicInfo.getX() < minX) { |
| | | minX = artifactGraphicInfo.getX(); |
| | | } |
| | | // height |
| | | if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) { |
| | | maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight(); |
| | | } |
| | | if (artifactGraphicInfo.getY() < minY) { |
| | | minY = artifactGraphicInfo.getY(); |
| | | } |
| | | } |
| | | |
| | | List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId()); |
| | | if (graphicInfoList != null) { |
| | | for (GraphicInfo graphicInfo : graphicInfoList) { |
| | | // width |
| | | if (graphicInfo.getX() > maxX) { |
| | | maxX = graphicInfo.getX(); |
| | | } |
| | | if (graphicInfo.getX() < minX) { |
| | | minX = graphicInfo.getX(); |
| | | } |
| | | // height |
| | | if (graphicInfo.getY() > maxY) { |
| | | maxY = graphicInfo.getY(); |
| | | } |
| | | if (graphicInfo.getY() < minY) { |
| | | minY = graphicInfo.getY(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | int nrOfLanes = 0; |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | for (Lane l : process.getLanes()) { |
| | | |
| | | nrOfLanes++; |
| | | |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(l.getId()); |
| | | // // width |
| | | if (graphicInfo.getX() + graphicInfo.getWidth() > maxX) { |
| | | maxX = graphicInfo.getX() + graphicInfo.getWidth(); |
| | | } |
| | | if (graphicInfo.getX() < minX) { |
| | | minX = graphicInfo.getX(); |
| | | } |
| | | // height |
| | | if (graphicInfo.getY() + graphicInfo.getHeight() > maxY) { |
| | | maxY = graphicInfo.getY() + graphicInfo.getHeight(); |
| | | } |
| | | if (graphicInfo.getY() < minY) { |
| | | minY = graphicInfo.getY(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Special case, see https://activiti.atlassian.net/browse/ACT-1431 |
| | | if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) { |
| | | // Nothing to show |
| | | minX = 0; |
| | | minY = 0; |
| | | } |
| | | |
| | | return new CustomDefaultProcessDiagramCanvas((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY, |
| | | imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); |
| | | } |
| | | |
| | | protected static List<Artifact> gatherAllArtifacts(BpmnModel bpmnModel) { |
| | | List<Artifact> artifacts = new ArrayList<>(); |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | artifacts.addAll(process.getArtifacts()); |
| | | } |
| | | return artifacts; |
| | | } |
| | | |
| | | protected static List<FlowNode> gatherAllFlowNodes(BpmnModel bpmnModel) { |
| | | List<FlowNode> flowNodes = new ArrayList<>(); |
| | | for (Process process : bpmnModel.getProcesses()) { |
| | | flowNodes.addAll(gatherAllFlowNodes(process)); |
| | | } |
| | | return flowNodes; |
| | | } |
| | | |
| | | protected static List<FlowNode> gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) { |
| | | List<FlowNode> flowNodes = new ArrayList<>(); |
| | | for (FlowElement flowElement : flowElementsContainer.getFlowElements()) { |
| | | if (flowElement instanceof FlowNode) { |
| | | flowNodes.add((FlowNode) flowElement); |
| | | } |
| | | if (flowElement instanceof FlowElementsContainer) { |
| | | flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement)); |
| | | } |
| | | } |
| | | return flowNodes; |
| | | } |
| | | |
| | | protected boolean isPartOfCollapsedSubProcess(FlowElement flowElement, BpmnModel model) { |
| | | SubProcess subProcess = flowElement.getSubProcess(); |
| | | if (subProcess != null) { |
| | | GraphicInfo graphicInfo = model.getGraphicInfo(subProcess.getId()); |
| | | if (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { |
| | | return true; |
| | | } |
| | | |
| | | return isPartOfCollapsedSubProcess(subProcess, model); |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | public Map<Class<? extends BaseElement>, ActivityDrawInstruction> getActivityDrawInstructions() { |
| | | return activityDrawInstructions; |
| | | } |
| | | |
| | | public void setActivityDrawInstructions( |
| | | Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions) { |
| | | this.activityDrawInstructions = activityDrawInstructions; |
| | | } |
| | | |
| | | public Map<Class<? extends BaseElement>, ArtifactDrawInstruction> getArtifactDrawInstructions() { |
| | | return artifactDrawInstructions; |
| | | } |
| | | |
| | | public void setArtifactDrawInstructions( |
| | | Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions) { |
| | | this.artifactDrawInstructions = artifactDrawInstructions; |
| | | } |
| | | |
| | | protected interface ActivityDrawInstruction { |
| | | void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode); |
| | | } |
| | | |
| | | protected interface ArtifactDrawInstruction { |
| | | void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static org.dromara.workflow.common.constant.FlowConstant.NUMBER_OF_INSTANCES; |
| | | |
| | | /** |
| | | * 串è¡å ç¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | public class AddSequenceMultiInstanceCmd implements Command<Void> { |
| | | |
| | | /** |
| | | * æ§è¡id |
| | | */ |
| | | private final String executionId; |
| | | |
| | | /** |
| | | * ä¼ç¾äººåéåKEY |
| | | */ |
| | | private final String assigneeList; |
| | | |
| | | /** |
| | | * å ç¾äººå |
| | | */ |
| | | private final List<Long> assignees; |
| | | |
| | | public AddSequenceMultiInstanceCmd(String executionId, String assigneeList, List<Long> assignees) { |
| | | this.executionId = executionId; |
| | | this.assigneeList = assigneeList; |
| | | this.assignees = assignees; |
| | | } |
| | | |
| | | @Override |
| | | public Void execute(CommandContext commandContext) { |
| | | ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); |
| | | ExecutionEntity entity = executionEntityManager.findById(executionId); |
| | | // å¤å®ä¾ä»»å¡æ»æ°å assignees.size() |
| | | if (entity.getVariable(NUMBER_OF_INSTANCES) instanceof Integer nrOfInstances) { |
| | | entity.setVariable(NUMBER_OF_INSTANCES, nrOfInstances + assignees.size()); |
| | | } |
| | | // 设置æµç¨åé |
| | | if (entity.getVariable(assigneeList) instanceof List<?> userIds) { |
| | | CollUtil.addAll(userIds, assignees); |
| | | Map<String, Object> variables = new HashMap<>(16); |
| | | variables.put(assigneeList, userIds); |
| | | entity.setVariables(variables); |
| | | } |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import org.dromara.common.core.domain.dto.OssDTO; |
| | | import org.dromara.common.core.service.OssService; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.AttachmentEntity; |
| | | import org.flowable.engine.impl.persistence.entity.AttachmentEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éä»¶ä¸ä¼ |
| | | * |
| | | * @author may |
| | | */ |
| | | public class AttachmentCmd implements Command<Boolean> { |
| | | |
| | | private final String fileId; |
| | | |
| | | private final String taskId; |
| | | |
| | | private final String processInstanceId; |
| | | |
| | | public AttachmentCmd(String fileId, String taskId, String processInstanceId) { |
| | | this.fileId = fileId; |
| | | this.taskId = taskId; |
| | | this.processInstanceId = processInstanceId; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean execute(CommandContext commandContext) { |
| | | try { |
| | | if (StringUtils.isNotBlank(fileId)) { |
| | | List<OssDTO> ossList = SpringUtils.getBean(OssService.class).selectByIds(fileId); |
| | | if (CollUtil.isNotEmpty(ossList)) { |
| | | for (OssDTO oss : ossList) { |
| | | AttachmentEntityManager attachmentEntityManager = CommandContextUtil.getAttachmentEntityManager(); |
| | | AttachmentEntity attachmentEntity = attachmentEntityManager.create(); |
| | | attachmentEntity.setRevision(1); |
| | | attachmentEntity.setUserId(LoginHelper.getUserId().toString()); |
| | | attachmentEntity.setName(oss.getOriginalName()); |
| | | attachmentEntity.setDescription(oss.getOriginalName()); |
| | | attachmentEntity.setType(oss.getFileSuffix()); |
| | | attachmentEntity.setTaskId(taskId); |
| | | attachmentEntity.setProcessInstanceId(processInstanceId); |
| | | attachmentEntity.setContentId(oss.getOssId().toString()); |
| | | attachmentEntity.setTime(new Date()); |
| | | attachmentEntityManager.insert(attachmentEntity); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | return true; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * å 餿§è¡æ°æ® |
| | | * |
| | | * @author may |
| | | */ |
| | | public class DeleteExecutionCmd implements Command<Void>, Serializable { |
| | | |
| | | /** |
| | | * æ§è¡id |
| | | */ |
| | | private final String executionId; |
| | | |
| | | public DeleteExecutionCmd(String executionId) { |
| | | this.executionId = executionId; |
| | | } |
| | | |
| | | @Override |
| | | public Void execute(CommandContext commandContext) { |
| | | ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); |
| | | ExecutionEntity entity = executionEntityManager.findById(executionId); |
| | | if (entity != null) { |
| | | executionEntityManager.deleteExecutionAndRelatedData(entity, "", false, false); |
| | | } |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static org.dromara.workflow.common.constant.FlowConstant.LOOP_COUNTER; |
| | | import static org.dromara.workflow.common.constant.FlowConstant.NUMBER_OF_INSTANCES; |
| | | |
| | | |
| | | /** |
| | | * 串è¡åç¾ |
| | | * |
| | | * @author may |
| | | */ |
| | | @AllArgsConstructor |
| | | public class DeleteSequenceMultiInstanceCmd implements Command<Void> { |
| | | |
| | | /** |
| | | * å½åèç¹å®¡æ¹äººåid |
| | | */ |
| | | private final String currentUserId; |
| | | |
| | | /** |
| | | * æ§è¡id |
| | | */ |
| | | private final String executionId; |
| | | |
| | | /** |
| | | * ä¼ç¾äººåéåKEY |
| | | */ |
| | | private final String assigneeList; |
| | | |
| | | /** |
| | | * åç¾äººå |
| | | */ |
| | | private final List<Long> assignees; |
| | | |
| | | |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public Void execute(CommandContext commandContext) { |
| | | ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); |
| | | ExecutionEntity entity = executionEntityManager.findById(executionId); |
| | | // 设置æµç¨åé |
| | | List<Long> userIds = new ArrayList<>(); |
| | | List<Object> variable = (List<Object>) entity.getVariable(assigneeList); |
| | | for (Object o : variable) { |
| | | userIds.add(Long.valueOf(o.toString())); |
| | | } |
| | | List<Long> userIdList = new ArrayList<>(); |
| | | userIds.forEach(e -> { |
| | | Long userId = assignees.stream().filter(id -> ObjectUtil.equals(id, e)).findFirst().orElse(null); |
| | | if (userId == null) { |
| | | userIdList.add(e); |
| | | } |
| | | }); |
| | | // å½å任塿§è¡ä½ç½® |
| | | int loopCounterIndex = -1; |
| | | for (int i = 0; i < userIdList.size(); i++) { |
| | | Long userId = userIdList.get(i); |
| | | if (currentUserId.equals(userId.toString())) { |
| | | loopCounterIndex = i; |
| | | } |
| | | } |
| | | Map<String, Object> variables = new HashMap<>(16); |
| | | variables.put(NUMBER_OF_INSTANCES, userIdList.size()); |
| | | variables.put(assigneeList, userIdList); |
| | | variables.put(LOOP_COUNTER, loopCounterIndex); |
| | | entity.setVariables(variables); |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * è·åå¹¶è¡ç½å
³æ§è¡åä¿ççæ§è¡å®ä¾æ°æ® |
| | | * |
| | | * @author may |
| | | */ |
| | | public class ExecutionChildByExecutionIdCmd implements Command<List<ExecutionEntity>>, Serializable { |
| | | |
| | | /** |
| | | * å½å任塿§è¡å®ä¾id |
| | | */ |
| | | private final String executionId; |
| | | |
| | | public ExecutionChildByExecutionIdCmd(String executionId) { |
| | | this.executionId = executionId; |
| | | } |
| | | |
| | | @Override |
| | | public List<ExecutionEntity> execute(CommandContext commandContext) { |
| | | ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); |
| | | // è·åå½åæ§è¡æ°æ® |
| | | ExecutionEntity executionEntity = executionEntityManager.findById(executionId); |
| | | // éè¿å½åæ§è¡æ°æ®çç¶æ§è¡ï¼æ¥è¯¢ææåæ§è¡æ°æ® |
| | | List<ExecutionEntity> allChildrenExecution = |
| | | executionEntityManager.collectChildren(executionEntity.getParent()); |
| | | return StreamUtils.filter(allChildrenExecution, e -> !e.isActive()); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntity; |
| | | import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntityManager; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨ç¶æ |
| | | * |
| | | * @author may |
| | | */ |
| | | public class UpdateBusinessStatusCmd implements Command<Boolean> { |
| | | |
| | | private final String processInstanceId; |
| | | private final String status; |
| | | |
| | | public UpdateBusinessStatusCmd(String processInstanceId, String status) { |
| | | this.processInstanceId = processInstanceId; |
| | | this.status = status; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean execute(CommandContext commandContext) { |
| | | try { |
| | | HistoricProcessInstanceEntityManager manager = CommandContextUtil.getHistoricProcessInstanceEntityManager(); |
| | | HistoricProcessInstanceEntity processInstance = manager.findById(processInstanceId); |
| | | processInstance.setBusinessStatus(status); |
| | | manager.update(processInstance); |
| | | return true; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.cmd; |
| | | |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.flowable.common.engine.impl.interceptor.Command; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | import org.flowable.task.service.HistoricTaskService; |
| | | import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨åå² |
| | | * |
| | | * @author may |
| | | */ |
| | | public class UpdateHiTaskInstCmd implements Command<Boolean> { |
| | | |
| | | private final List<String> taskIds; |
| | | |
| | | private final String processDefinitionId; |
| | | |
| | | private final String processInstanceId; |
| | | |
| | | public UpdateHiTaskInstCmd(List<String> taskIds, String processDefinitionId, String processInstanceId) { |
| | | this.taskIds = taskIds; |
| | | this.processDefinitionId = processDefinitionId; |
| | | this.processInstanceId = processInstanceId; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean execute(CommandContext commandContext) { |
| | | try { |
| | | HistoricTaskService historicTaskService = CommandContextUtil.getHistoricTaskService(); |
| | | for (String taskId : taskIds) { |
| | | HistoricTaskInstanceEntity historicTask = historicTaskService.getHistoricTask(taskId); |
| | | if (historicTask != null) { |
| | | historicTask.setProcessDefinitionId(processDefinitionId); |
| | | historicTask.setProcessInstanceId(processInstanceId); |
| | | historicTask.setCreateTime(new Date()); |
| | | CommandContextUtil.getHistoricTaskService().updateHistoricTask(historicTask, true); |
| | | } |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.config; |
| | | |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import org.dromara.workflow.flowable.handler.TaskTimeoutJobHandler; |
| | | import org.flowable.spring.SpringProcessEngineConfiguration; |
| | | import org.flowable.spring.boot.EngineConfigurationConfigurer; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.util.Collections; |
| | | |
| | | |
| | | /** |
| | | * flowableé
ç½® |
| | | * |
| | | * @author may |
| | | */ |
| | | @Configuration |
| | | public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> { |
| | | |
| | | @Autowired |
| | | private GlobalFlowableListener globalFlowableListener; |
| | | @Autowired |
| | | private IdentifierGenerator identifierGenerator; |
| | | |
| | | @Override |
| | | public void configure(SpringProcessEngineConfiguration processEngineConfiguration) { |
| | | processEngineConfiguration.setIdGenerator(() -> identifierGenerator.nextId(null).toString()); |
| | | processEngineConfiguration.setEventListeners(Collections.singletonList(globalFlowableListener)); |
| | | processEngineConfiguration.addCustomJobHandler(new TaskTimeoutJobHandler()); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.config; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.workflow.common.enums.TaskStatusEnum; |
| | | import org.dromara.workflow.flowable.handler.TaskTimeoutJobHandler; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.bpmn.model.BoundaryEvent; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | import org.flowable.bpmn.model.FlowElement; |
| | | import org.flowable.common.engine.api.delegate.event.*; |
| | | import org.flowable.common.engine.impl.cfg.TransactionState; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.RuntimeService; |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | import org.flowable.engine.runtime.Execution; |
| | | import org.flowable.engine.task.Comment; |
| | | import org.flowable.job.service.TimerJobService; |
| | | import org.flowable.job.service.impl.persistence.entity.JobEntity; |
| | | import org.flowable.job.service.impl.persistence.entity.TimerJobEntity; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.service.impl.persistence.entity.TaskEntity; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 弿è°åº¦çå¬ |
| | | * |
| | | * @author may |
| | | */ |
| | | @Component |
| | | public class GlobalFlowableListener implements FlowableEventListener { |
| | | |
| | | @Autowired |
| | | @Lazy |
| | | private TaskService taskService; |
| | | |
| | | @Autowired |
| | | @Lazy |
| | | private RuntimeService runtimeService; |
| | | |
| | | @Autowired |
| | | @Lazy |
| | | private RepositoryService repositoryService; |
| | | |
| | | @Value("${flowable.async-executor-activate}") |
| | | private boolean asyncExecutorActivate; |
| | | |
| | | @Override |
| | | public void onEvent(FlowableEvent flowableEvent) { |
| | | if (flowableEvent instanceof FlowableEngineEvent flowableEngineEvent) { |
| | | FlowableEngineEventType engineEventType = (FlowableEngineEventType) flowableEvent.getType(); |
| | | switch (engineEventType) { |
| | | case JOB_EXECUTION_SUCCESS -> jobExecutionSuccess((FlowableEngineEntityEvent) flowableEngineEvent); |
| | | case TASK_DUEDATE_CHANGED, TASK_CREATED -> { |
| | | FlowableEntityEvent flowableEntityEvent = (FlowableEntityEvent) flowableEngineEvent; |
| | | Object entityObject = flowableEntityEvent.getEntity(); |
| | | TaskEntity task = (TaskEntity) entityObject; |
| | | if (asyncExecutorActivate && task.getDueDate() != null && task.getDueDate().after(new Date())) { |
| | | //å é¤ä¹åå·²ç»åå¨ç宿¶ä»»å¡ |
| | | TimerJobService timerJobService = CommandContextUtil.getTimerJobService(); |
| | | List<TimerJobEntity> timerJobEntityList = timerJobService.findTimerJobsByProcessInstanceId(task.getProcessInstanceId()); |
| | | if (!CollUtil.isEmpty(timerJobEntityList)) { |
| | | for (TimerJobEntity timerJobEntity : timerJobEntityList) { |
| | | String taskId = timerJobEntity.getJobHandlerConfiguration(); |
| | | if (task.getId().equals(taskId)) { |
| | | timerJobService.deleteTimerJob(timerJobEntity); |
| | | } |
| | | } |
| | | } |
| | | //å建job对象 |
| | | TimerJobEntity timer = timerJobService.createTimerJob(); |
| | | timer.setTenantId(TenantHelper.getTenantId()); |
| | | //设置jobç±»å |
| | | timer.setJobType(JobEntity.JOB_TYPE_TIMER); |
| | | timer.setJobHandlerType(TaskTimeoutJobHandler.TYPE); |
| | | timer.setDuedate(task.getDueDate()); |
| | | timer.setProcessInstanceId(task.getProcessInstanceId()); |
| | | //设置任å¡id |
| | | timer.setJobHandlerConfiguration(task.getId()); |
| | | //ä¿å并触åäºä»¶ |
| | | timerJobService.scheduleTimerJob(timer); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean isFailOnException() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isFireOnTransactionLifecycleEvent() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public String getOnTransaction() { |
| | | return TransactionState.COMMITTED.name(); |
| | | } |
| | | |
| | | /** |
| | | * å¤çè¾¹ç宿¶äºä»¶èªå¨å®¡æ¹è®°å½ |
| | | * |
| | | * @param event äºä»¶ |
| | | */ |
| | | protected void jobExecutionSuccess(FlowableEngineEntityEvent event) { |
| | | if (event != null && StringUtils.isNotBlank(event.getExecutionId())) { |
| | | Execution execution = runtimeService.createExecutionQuery().executionId(event.getExecutionId()).singleResult(); |
| | | if (execution != null) { |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(event.getProcessDefinitionId()); |
| | | FlowElement flowElement = bpmnModel.getFlowElement(execution.getActivityId()); |
| | | if (flowElement instanceof BoundaryEvent) { |
| | | String attachedToRefId = ((BoundaryEvent) flowElement).getAttachedToRefId(); |
| | | List<Execution> list = runtimeService.createExecutionQuery().activityId(attachedToRefId).list(); |
| | | for (Execution ex : list) { |
| | | Task task = QueryUtils.taskQuery().executionId(ex.getId()).singleResult(); |
| | | if (task != null) { |
| | | List<Comment> taskComments = taskService.getTaskComments(task.getId()); |
| | | if (CollUtil.isEmpty(taskComments)) { |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), "è¶
æ¶èªå¨å®¡æ¹!"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.handler; |
| | | |
| | | import org.dromara.workflow.common.enums.TaskStatusEnum; |
| | | import org.flowable.common.engine.impl.interceptor.CommandContext; |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.impl.jobexecutor.TimerEventHandler; |
| | | import org.flowable.engine.impl.util.CommandContextUtil; |
| | | import org.flowable.job.service.JobHandler; |
| | | import org.flowable.job.service.impl.persistence.entity.JobEntity; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.api.TaskQuery; |
| | | import org.flowable.variable.api.delegate.VariableScope; |
| | | |
| | | /** |
| | | * åçè¶
æ¶(è¿æ)ä»»å¡ |
| | | * |
| | | * @author may |
| | | */ |
| | | public class TaskTimeoutJobHandler extends TimerEventHandler implements JobHandler { |
| | | |
| | | public static final String TYPE = "taskTimeout"; |
| | | |
| | | @Override |
| | | public String getType() { |
| | | return TYPE; |
| | | } |
| | | |
| | | @Override |
| | | public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) { |
| | | TaskService taskService = CommandContextUtil.getProcessEngineConfiguration(commandContext) |
| | | .getTaskService(); |
| | | Task task = taskService.createTaskQuery().taskId(configuration).singleResult(); |
| | | if (task != null) { |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.TIMEOUT.getStatus(), "è¶
æ¶èªå¨å®¡æ¹!"); |
| | | taskService.complete(configuration); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.strategy; |
| | | |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.workflow.annotation.FlowListenerAnnotation; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.beans.factory.config.BeanPostProcessor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨ä»»å¡çå¬çç¥ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | @Component |
| | | public class FlowEventStrategy implements BeanPostProcessor { |
| | | |
| | | private final Map<String, FlowTaskEventHandler> flowTaskEventHandlers = new HashMap<>(); |
| | | private final Map<String, FlowProcessEventHandler> flowProcessEventHandlers = new HashMap<>(); |
| | | |
| | | @Override |
| | | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
| | | if (bean instanceof FlowTaskEventHandler) { |
| | | FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class); |
| | | if (null != annotation) { |
| | | if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isNotBlank(annotation.taskDefId())) { |
| | | String id = annotation.processDefinitionKey() + "_" + annotation.taskDefId(); |
| | | if (!flowTaskEventHandlers.containsKey(id)) { |
| | | flowTaskEventHandlers.put(id, (FlowTaskEventHandler) bean); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (bean instanceof FlowProcessEventHandler) { |
| | | FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class); |
| | | if (null != annotation) { |
| | | if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isBlank(annotation.taskDefId())) { |
| | | if (!flowProcessEventHandlers.containsKey(annotation.processDefinitionKey())) { |
| | | flowProcessEventHandlers.put(annotation.processDefinitionKey(), (FlowProcessEventHandler) bean); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); |
| | | } |
| | | |
| | | /** |
| | | * è·å坿§è¡bean |
| | | * |
| | | * @param key key |
| | | */ |
| | | public FlowTaskEventHandler getTaskHandler(String key) { |
| | | if (!flowTaskEventHandlers.containsKey(key)) { |
| | | return null; |
| | | } |
| | | return flowTaskEventHandlers.get(key); |
| | | } |
| | | |
| | | /** |
| | | * è·å坿§è¡bean |
| | | * |
| | | * @param key key |
| | | */ |
| | | public FlowProcessEventHandler getProcessHandler(String key) { |
| | | if (!flowProcessEventHandlers.containsKey(key)) { |
| | | return null; |
| | | } |
| | | return flowProcessEventHandlers.get(key); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.strategy; |
| | | |
| | | |
| | | /** |
| | | * æµç¨çå¬ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | public interface FlowProcessEventHandler { |
| | | |
| | | /** |
| | | * æ§è¡åçä»»å¡çå¬ |
| | | * |
| | | * @param businessKey ä¸å¡id |
| | | * @param status ç¶æ |
| | | * @param submit å½ä¸ºtrueæ¶ä¸ºç³è¯·äººèç¹åç |
| | | */ |
| | | void handleProcess(String businessKey, String status, boolean submit); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.flowable.strategy; |
| | | |
| | | |
| | | /** |
| | | * æµç¨ä»»å¡çå¬ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | public interface FlowTaskEventHandler { |
| | | |
| | | /** |
| | | * æ§è¡åçä»»å¡çå¬ |
| | | * |
| | | * @param taskId ä»»å¡ID |
| | | * @param businessKey ä¸å¡id |
| | | */ |
| | | void handleTask(String taskId, String businessKey); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.listener; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.workflow.annotation.FlowListenerAnnotation; |
| | | import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * èªå®ä¹ç嬿µè¯ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @FlowListenerAnnotation(processDefinitionKey = "leave1") |
| | | public class TestCustomProcessHandler implements FlowProcessEventHandler { |
| | | |
| | | |
| | | /** |
| | | * æ§è¡åçä»»å¡çå¬ |
| | | * |
| | | * @param businessKey ä¸å¡id |
| | | * @param status ç¶æ |
| | | * @param submit å½ä¸ºtrueæ¶ä¸ºç³è¯·äººèç¹åç |
| | | */ |
| | | @Override |
| | | public void handleProcess(String businessKey, String status, boolean submit) { |
| | | log.info("ä¸å¡ID:" + businessKey + ",ç¶æ:" + status); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.listener; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.workflow.annotation.FlowListenerAnnotation; |
| | | import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * èªå®ä¹ç嬿µè¯ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-27 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @FlowListenerAnnotation(processDefinitionKey = "leave1", taskDefId = "Activity_14633hx") |
| | | public class TestCustomTaskHandler implements FlowTaskEventHandler { |
| | | |
| | | @Override |
| | | public void handleTask(String taskId, String businessKey) { |
| | | log.info("ä»»å¡ID:" + taskId + ",ä¸å¡ID:" + businessKey); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.listener; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.delegate.DelegateExecution; |
| | | import org.flowable.engine.delegate.ExecutionListener; |
| | | import org.flowable.task.api.Task; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ç嬿µè¯ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-12 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Component("testLeaveExecutionListener") |
| | | public class TestLeaveExecutionListener implements ExecutionListener { |
| | | |
| | | @Override |
| | | public void notify(DelegateExecution execution) { |
| | | Task task = QueryUtils.taskQuery().executionId(execution.getId()).singleResult(); |
| | | log.info("æ§è¡çå¬ã" + task.getName() + "ã"); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.listener; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.task.service.delegate.DelegateTask; |
| | | import org.flowable.task.service.delegate.TaskListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * æµç¨ä»»å¡ç嬿µè¯ |
| | | * |
| | | * @author may |
| | | * @date 2023-12-12 |
| | | */ |
| | | @Slf4j |
| | | @Component("testLeaveTaskListener") |
| | | public class TestLeaveTaskListener implements TaskListener { |
| | | @Override |
| | | public void notify(DelegateTask delegateTask) { |
| | | log.info("æ§è¡çå¬ã" + delegateTask.getName() + "ã"); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.workflow.domain.ActHiProcinst; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-07-22 |
| | | */ |
| | | @InterceptorIgnore(tenantLine = "true") |
| | | public interface ActHiProcinstMapper extends BaseMapperPlus<ActHiProcinst, ActHiProcinst> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import org.dromara.workflow.domain.ActHiTaskinst; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * æµç¨åå²ä»»å¡Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-02 |
| | | */ |
| | | @InterceptorIgnore(tenantLine = "true") |
| | | public interface ActHiTaskinstMapper extends BaseMapperPlus<ActHiTaskinst, ActHiTaskinst> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.workflow.domain.vo.TaskVo; |
| | | |
| | | |
| | | /** |
| | | * ä»»å¡ä¿¡æ¯Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-02 |
| | | */ |
| | | @InterceptorIgnore(tenantLine = "true") |
| | | public interface ActTaskMapper extends BaseMapperPlus<TaskVo, TaskVo> { |
| | | /** |
| | | * è·åå¾
åä¿¡æ¯ |
| | | * |
| | | * @param page å页 |
| | | * @param queryWrapper æ¡ä»¶ |
| | | * @return ç»æ |
| | | */ |
| | | Page<TaskVo> getTaskWaitByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) Wrapper<TaskVo> queryWrapper); |
| | | |
| | | /** |
| | | * è·åå·²å |
| | | * |
| | | * @param page å页 |
| | | * @param queryWrapper æ¡ä»¶ |
| | | * @return ç»æ |
| | | */ |
| | | Page<TaskVo> getTaskFinishByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) Wrapper<TaskVo> queryWrapper); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çæé |
| | | * |
| | | * @param page å页 |
| | | * @param queryWrapper æ¡ä»¶ |
| | | * @return ç»æ |
| | | */ |
| | | Page<TaskVo> getTaskCopyByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) QueryWrapper<TaskVo> queryWrapper); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.workflow.domain.TestLeave; |
| | | import org.dromara.workflow.domain.vo.TestLeaveVo; |
| | | |
| | | /** |
| | | * 请åMapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | public interface TestLeaveMapper extends BaseMapperPlus<TestLeave, TestLeaveVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | import org.dromara.workflow.domain.vo.WfCategoryVo; |
| | | |
| | | /** |
| | | * æµç¨åç±»Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-06-27 |
| | | */ |
| | | public interface WfCategoryMapper extends BaseMapperPlus<WfCategory, WfCategoryVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.workflow.domain.WfDefinitionConfig; |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½®Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | public interface WfDefinitionConfigMapper extends BaseMapperPlus<WfDefinitionConfig, WfDefinitionConfigVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.workflow.domain.WfFormManage; |
| | | import org.dromara.workflow.domain.vo.WfFormManageVo; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * 表å管çMapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | public interface WfFormManageMapper extends BaseMapperPlus<WfFormManage, WfFormManageVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.workflow.domain.vo.WfNodeConfigVo; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * èç¹é
ç½®Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | public interface WfNodeConfigMapper extends BaseMapperPlus<WfNodeConfig, WfNodeConfigVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.mapper; |
| | | |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.dromara.workflow.domain.WfTaskBackNode; |
| | | |
| | | /** |
| | | * èç¹é©³åè®°å½Mapperæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-13 |
| | | */ |
| | | public interface WfTaskBackNodeMapper extends BaseMapperPlus<WfTaskBackNode, WfTaskBackNode> { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | |
| | | import org.dromara.workflow.domain.ActHiProcinst; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-07-22 |
| | | */ |
| | | public interface IActHiProcinstService { |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idæ¥è¯¢ |
| | | * |
| | | * @param businessKeys ä¸å¡id |
| | | * @return ç»æ |
| | | */ |
| | | List<ActHiProcinst> selectByBusinessKeyIn(List<String> businessKeys); |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idæ¥è¯¢ |
| | | * |
| | | * @param businessKey ä¸å¡id |
| | | * @return ç»æ |
| | | */ |
| | | ActHiProcinst selectByBusinessKey(String businessKey); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | |
| | | /** |
| | | * æµç¨åå²ä»»å¡Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-02 |
| | | */ |
| | | public interface IActHiTaskinstService { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.bo.ModelBo; |
| | | import org.dromara.workflow.domain.vo.ModelVo; |
| | | import org.flowable.engine.repository.Model; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 模åç®¡ç æå¡å± |
| | | * |
| | | * @author may |
| | | */ |
| | | public interface IActModelService { |
| | | /** |
| | | * å页æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param modelBo 模ååæ° |
| | | * @param pageQuery åæ° |
| | | * @return è¿åå页å表 |
| | | */ |
| | | TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ°å¢æ¨¡å |
| | | * |
| | | * @param modelBo 模å请æ±å¯¹è±¡ |
| | | * @return ç»æ |
| | | */ |
| | | boolean saveNewModel(ModelBo modelBo); |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param modelId 模åid |
| | | * @return æ¨¡åæ°æ® |
| | | */ |
| | | ModelVo getInfo(String modelId); |
| | | |
| | | /** |
| | | * ä¿®æ¹æ¨¡åä¿¡æ¯ |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | boolean update(ModelBo modelBo); |
| | | |
| | | /** |
| | | * ç¼è¾æ¨¡åXML |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | boolean editModelXml(ModelBo modelBo); |
| | | |
| | | /** |
| | | * 模åé¨ç½² |
| | | * |
| | | * @param id 模åid |
| | | * @return ç»æ |
| | | */ |
| | | boolean modelDeploy(String id); |
| | | |
| | | /** |
| | | * å¯¼åºæ¨¡åzipå缩å
|
| | | * |
| | | * @param modelIds 模åid |
| | | * @param response ååº |
| | | */ |
| | | void exportZip(List<String> modelIds, HttpServletResponse response); |
| | | |
| | | /** |
| | | * å¤å¶æ¨¡å |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | boolean copyModel(ModelBo modelBo); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.bo.ProcessDefinitionBo; |
| | | import org.dromara.workflow.domain.vo.ProcessDefinitionVo; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ æå¡å± |
| | | * |
| | | * @author may |
| | | */ |
| | | public interface IActProcessDefinitionService { |
| | | /** |
| | | * å页æ¥è¯¢ |
| | | * |
| | | * @param processDefinitionBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return è¿åå页å表 |
| | | */ |
| | | TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo processDefinitionBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å岿µç¨å®ä¹å表 |
| | | * |
| | | * @param key æµç¨å®ä¹key |
| | | * @return ç»æ |
| | | */ |
| | | List<ProcessDefinitionVo> getListByKey(String key); |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹å¾ç |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | String definitionImage(String processDefinitionId); |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹xmlæä»¶ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | String definitionXml(String processDefinitionId); |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¹ |
| | | * |
| | | * @param deploymentIds é¨ç½²id |
| | | * @param processDefinitionIds æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteDeployment(List<String> deploymentIds, List<String> processDefinitionIds); |
| | | |
| | | /** |
| | | * æ¿æ´»æè
æèµ·æµç¨å®ä¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | boolean updateDefinitionState(String processDefinitionId); |
| | | |
| | | /** |
| | | * è¿ç§»æµç¨å®ä¹ |
| | | * |
| | | * @param currentProcessDefinitionId å½åæµç¨å®ä¹id |
| | | * @param fromProcessDefinitionId éè¦è¿ç§»å°çæµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | boolean migrationDefinition(String currentProcessDefinitionId, String fromProcessDefinitionId); |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è½¬æ¢ä¸ºæ¨¡å |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | boolean convertToModel(String processDefinitionId); |
| | | |
| | | /** |
| | | * éè¿zipæxmlé¨ç½²æµç¨å®ä¹ |
| | | * |
| | | * @param file æä»¶ |
| | | * @param categoryCode åç±» |
| | | */ |
| | | void deployByFile(MultipartFile file, String categoryCode); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.bo.ProcessInstanceBo; |
| | | import org.dromara.workflow.domain.bo.ProcessInvalidBo; |
| | | import org.dromara.workflow.domain.bo.TaskUrgingBo; |
| | | import org.dromara.workflow.domain.vo.ActHistoryInfoVo; |
| | | import org.dromara.workflow.domain.vo.ProcessInstanceVo; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ æå¡å± |
| | | * |
| | | * @author may |
| | | */ |
| | | public interface IActProcessInstanceService { |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | String getHistoryImage(String processInstanceId); |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾è¿è¡ä¸ï¼åå²çèç¹ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | Map<String, Object> getHistoryList(String processInstanceId); |
| | | |
| | | /** |
| | | * å页æ¥è¯¢æ£å¨è¿è¡çæµç¨å®ä¾ |
| | | * |
| | | * @param processInstanceBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo processInstanceBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å·²ç»æçæµç¨å®ä¾ |
| | | * |
| | | * @param processInstanceBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo processInstanceBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * è·å审æ¹è®°å½ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | List<ActHistoryInfoVo> getHistoryRecord(String processInstanceId); |
| | | |
| | | /** |
| | | * ä½åºæµç¨å®ä¾ï¼ä¸ä¼å é¤åå²è®°å½(å é¤è¿è¡ä¸çå®ä¾) |
| | | * |
| | | * @param processInvalidBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteRunInstance(ProcessInvalidBo processInvalidBo); |
| | | |
| | | /** |
| | | * è¿è¡ä¸çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteRunAndHisInstance(List<String> processInstanceIds); |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idå é¤ è¿è¡ä¸çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param businessKeys ä¸å¡id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteRunAndHisInstanceByBusinessKeys(List<String> businessKeys); |
| | | |
| | | /** |
| | | * 已宿çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteFinishAndHisInstance(List<String> processInstanceIds); |
| | | |
| | | /** |
| | | * æ¤éæµç¨ç³è¯· |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | boolean cancelProcessApply(String processInstanceId); |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å½åç»å½äººåæ® |
| | | * |
| | | * @param processInstanceBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo processInstanceBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * ä»»å¡å¬å(ç»å½åä»»å¡åç人åéç«å
ä¿¡ï¼é®ä»¶ï¼çä¿¡ç) |
| | | * |
| | | * @param taskUrgingBo ä»»å¡å¬å |
| | | * @return ç»æ |
| | | */ |
| | | boolean taskUrging(TaskUrgingBo taskUrgingBo); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.bo.*; |
| | | import org.dromara.workflow.domain.vo.TaskVo; |
| | | import org.dromara.workflow.domain.vo.VariableVo; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ä»»å¡ æå¡å± |
| | | * |
| | | * @author may |
| | | */ |
| | | public interface IActTaskService { |
| | | /** |
| | | * å¯å¨ä»»å¡ |
| | | * |
| | | * @param startProcessBo å¯å¨æµç¨åæ° |
| | | * @return ç»æ |
| | | */ |
| | | Map<String, Object> startWorkFlow(StartProcessBo startProcessBo); |
| | | |
| | | |
| | | /** |
| | | * åçä»»å¡ |
| | | * |
| | | * @param completeTaskBo åçä»»å¡åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean completeTask(CompleteTaskBo completeTaskBo); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery); |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | * @param pageQuery åæ° |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çæé |
| | | * |
| | | * @param taskBo åæ° |
| | | * @param pageQuery åæ° |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | * @param pageQuery åæ° |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | * |
| | | * @param delegateBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean delegateTask(DelegateBo delegateBo); |
| | | |
| | | /** |
| | | * ç»æ¢ä»»å¡ |
| | | * |
| | | * @param terminationBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean terminationTask(TerminationBo terminationBo); |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * |
| | | * @param transmitBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean transferTask(TransmitBo transmitBo); |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡å ç¾ |
| | | * |
| | | * @param addMultiBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean addMultiInstanceExecution(AddMultiBo addMultiBo); |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡åç¾ |
| | | * |
| | | * @param deleteMultiBo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteMultiInstanceExecution(DeleteMultiBo deleteMultiBo); |
| | | |
| | | /** |
| | | * 驳åå®¡æ¹ |
| | | * |
| | | * @param backProcessBo åæ° |
| | | * @return æµç¨å®ä¾id |
| | | */ |
| | | String backProcess(BackProcessBo backProcessBo); |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»»å¡åç人 |
| | | * |
| | | * @param taskIds ä»»å¡id |
| | | * @param userId åç人id |
| | | * @return ç»æ |
| | | */ |
| | | boolean updateAssignee(String[] taskIds, String userId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åé |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | * @return ç»æ |
| | | */ |
| | | List<VariableVo> getInstanceVariable(String taskId); |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµä»»å¡ç¨æ·éæ©å ç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | * @return ç»æ |
| | | */ |
| | | String getTaskUserIdsByAddMultiInstance(String taskId); |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµéæ©åç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | * @return ç»æ |
| | | */ |
| | | List<TaskVo> getListByDeleteMultiInstance(String taskId); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.TestLeave; |
| | | import org.dromara.workflow.domain.bo.TestLeaveBo; |
| | | import org.dromara.workflow.domain.vo.TestLeaveVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 请åServiceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | public interface ITestLeaveService { |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·å |
| | | */ |
| | | TestLeaveVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·åå表 |
| | | */ |
| | | TableDataInfo<TestLeaveVo> queryPageList(TestLeaveBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·åå表 |
| | | */ |
| | | List<TestLeaveVo> queryList(TestLeaveBo bo); |
| | | |
| | | /** |
| | | * æ°å¢è¯·å |
| | | */ |
| | | TestLeaveVo insertByBo(TestLeaveBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹è¯·å |
| | | */ |
| | | TestLeaveVo updateByBo(TestLeaveBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤è¯·åä¿¡æ¯ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | import org.dromara.workflow.domain.bo.WfCategoryBo; |
| | | import org.dromara.workflow.domain.vo.WfCategoryVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨åç±»Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2023-06-28 |
| | | */ |
| | | public interface IWfCategoryService { |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±» |
| | | */ |
| | | WfCategoryVo queryById(Long id); |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»å表 |
| | | */ |
| | | List<WfCategoryVo> queryList(WfCategoryBo bo); |
| | | |
| | | /** |
| | | * æ°å¢æµç¨åç±» |
| | | */ |
| | | Boolean insertByBo(WfCategoryBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨åç±» |
| | | */ |
| | | Boolean updateByBo(WfCategoryBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå 餿µç¨åç±»ä¿¡æ¯ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | | /** |
| | | * æç
§ç±»å«ç¼ç æ¥è¯¢ |
| | | * |
| | | * @param categoryCode åç±»æ¯å |
| | | * @return ç»æ |
| | | */ |
| | | WfCategory queryByCategoryCode(String categoryCode); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.workflow.domain.bo.WfDefinitionConfigBo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½®Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | public interface IWfDefinitionConfigService { |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | WfDefinitionConfigVo getByDefId(String definitionId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param tableName 表å |
| | | * @return ç»æ |
| | | */ |
| | | WfDefinitionConfigVo getByTableNameLastVersion(String tableName); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param tableName 表å |
| | | * @return ç»æ |
| | | */ |
| | | WfDefinitionConfigVo getByDefIdAndTableName(String definitionId, String tableName); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½®æé¤å½åæ¥è¯¢çæµç¨å®ä¹ |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param tableName 表å |
| | | * @return ç»æ |
| | | */ |
| | | List<WfDefinitionConfigVo> getByTableNameNotDefId(String tableName, String definitionId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½®å表 |
| | | * |
| | | * @param definitionIds æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | List<WfDefinitionConfigVo> queryList(List<String> definitionIds); |
| | | |
| | | |
| | | /** |
| | | * æ°å¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param bo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | Boolean saveOrUpdate(WfDefinitionConfigBo bo); |
| | | |
| | | /** |
| | | * å é¤ |
| | | * |
| | | * @param ids id |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteByIds(Collection<Long> ids); |
| | | |
| | | /** |
| | | * æç
§æµç¨å®ä¹idå é¤ |
| | | * |
| | | * @param ids æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteByDefIds(Collection<String> ids); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.workflow.domain.vo.WfFormManageVo; |
| | | import org.dromara.workflow.domain.bo.WfFormManageBo; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 表å管çServiceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | public interface IWfFormManageService { |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管ç |
| | | * |
| | | * @param id ä¸»é® |
| | | * @return ç»æ |
| | | */ |
| | | WfFormManageVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管ç |
| | | * |
| | | * @param ids ä¸»é® |
| | | * @return ç»æ |
| | | */ |
| | | List<WfFormManageVo> queryByIds(List<Long> ids); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | * |
| | | * @param bo åæ° |
| | | * @param pageQuery å页 |
| | | * @return ç»æ |
| | | */ |
| | | TableDataInfo<WfFormManageVo> queryPageList(WfFormManageBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | * |
| | | * @return ç»æ |
| | | */ |
| | | List<WfFormManageVo> selectList(); |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | * |
| | | * @param bo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | List<WfFormManageVo> queryList(WfFormManageBo bo); |
| | | |
| | | /** |
| | | * æ°å¢è¡¨å管ç |
| | | * |
| | | * @param bo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | Boolean insertByBo(WfFormManageBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹è¡¨å管ç |
| | | * |
| | | * @param bo åæ° |
| | | * @return ç»æ |
| | | */ |
| | | Boolean updateByBo(WfFormManageBo bo); |
| | | |
| | | /** |
| | | * æ¹éå é¤è¡¨å管çä¿¡æ¯ |
| | | * |
| | | * @param ids ä¸»é® |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteByIds(Collection<Long> ids); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.workflow.domain.vo.WfNodeConfigVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * èç¹é
ç½®Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | public interface IWfNodeConfigService { |
| | | |
| | | /** |
| | | * æ¥è¯¢èç¹é
ç½® |
| | | * |
| | | * @param id ä¸»é® |
| | | * @return ç»æ |
| | | */ |
| | | WfNodeConfigVo queryById(Long id); |
| | | |
| | | /** |
| | | * ä¿åèç¹é
ç½® |
| | | * |
| | | * @param list åæ° |
| | | * @return ç»æ |
| | | */ |
| | | Boolean saveOrUpdate(List<WfNodeConfig> list); |
| | | |
| | | /** |
| | | * æ¹éå é¤èç¹é
ç½®ä¿¡æ¯ |
| | | * |
| | | * @param ids ä¸»é® |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteByIds(Collection<Long> ids); |
| | | |
| | | /** |
| | | * æç
§æµç¨å®ä¹idå é¤ |
| | | * |
| | | * @param ids æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | Boolean deleteByDefIds(Collection<String> ids); |
| | | |
| | | /** |
| | | * æç
§æµç¨å®ä¹idæ¥è¯¢ |
| | | * |
| | | * @param ids æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | List<WfNodeConfigVo> selectByDefIds(Collection<String> ids); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service; |
| | | |
| | | |
| | | import org.dromara.workflow.domain.WfTaskBackNode; |
| | | import org.flowable.task.api.Task; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * èç¹é©³åè®°å½Serviceæ¥å£ |
| | | * |
| | | * @author may |
| | | * @date 2024-03-13 |
| | | */ |
| | | public interface IWfTaskBackNodeService { |
| | | |
| | | /** |
| | | * è®°å½å®¡æ¹èç¹ |
| | | * |
| | | * @param task ä»»å¡ |
| | | */ |
| | | void recordExecuteNode(Task task); |
| | | |
| | | /** |
| | | * ææµç¨å®ä¾idæ¥è¯¢ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | List<WfTaskBackNode> getListByInstanceId(String processInstanceId); |
| | | |
| | | /** |
| | | * æç
§æµç¨å®ä¾idï¼èç¹idæ¥è¯¢ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @param nodeId èç¹id |
| | | * @return ç»æ |
| | | */ |
| | | WfTaskBackNode getListByInstanceIdAndNodeId(String processInstanceId, String nodeId); |
| | | |
| | | /** |
| | | * å é¤é©³ååçèç¹ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @param targetActivityId èç¹id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteBackTaskNode(String processInstanceId, String targetActivityId); |
| | | |
| | | /** |
| | | * ææµç¨å®ä¾idå é¤ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteByInstanceId(String processInstanceId); |
| | | |
| | | /** |
| | | * ææµç¨å®ä¾idå é¤ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | * @return ç»æ |
| | | */ |
| | | boolean deleteByInstanceIds(List<String> processInstanceIds); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.workflow.domain.ActHiProcinst; |
| | | import org.dromara.workflow.mapper.ActHiProcinstMapper; |
| | | import org.dromara.workflow.service.IActHiProcinstService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * æµç¨å®ä¾Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2023-07-22 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActHiProcinstServiceImpl implements IActHiProcinstService { |
| | | |
| | | private final ActHiProcinstMapper baseMapper; |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idæ¥è¯¢ |
| | | * |
| | | * @param businessKeys ä¸å¡id |
| | | */ |
| | | @Override |
| | | public List<ActHiProcinst> selectByBusinessKeyIn(List<String> businessKeys) { |
| | | return baseMapper.selectList(new LambdaQueryWrapper<ActHiProcinst>() |
| | | .in(ActHiProcinst::getBusinessKey, businessKeys) |
| | | .eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId())); |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idæ¥è¯¢ |
| | | * |
| | | * @param businessKey ä¸å¡id |
| | | */ |
| | | @Override |
| | | public ActHiProcinst selectByBusinessKey(String businessKey) { |
| | | return baseMapper.selectOne(new LambdaQueryWrapper<ActHiProcinst>() |
| | | .eq(ActHiProcinst::getBusinessKey, businessKey) |
| | | .eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId())); |
| | | |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.dromara.workflow.service.IActHiTaskinstService; |
| | | |
| | | |
| | | /** |
| | | * æµç¨åå²ä»»å¡Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-02 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActHiTaskinstServiceImpl implements IActHiTaskinstService { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.Validator; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.core.util.ZipUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import com.alibaba.excel.util.StringUtils; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.apache.batik.transcoder.TranscoderInput; |
| | | import org.apache.batik.transcoder.TranscoderOutput; |
| | | import org.apache.batik.transcoder.image.PNGTranscoder; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.workflow.common.constant.FlowConstant; |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.workflow.domain.bo.ModelBo; |
| | | import org.dromara.workflow.domain.bo.WfDefinitionConfigBo; |
| | | import org.dromara.workflow.domain.vo.ModelVo; |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.workflow.service.IActModelService; |
| | | import org.dromara.workflow.service.IWfDefinitionConfigService; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | | import org.dromara.workflow.utils.ModelUtils; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.bpmn.model.UserTask; |
| | | import org.flowable.engine.RepositoryService; |
| | | 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.flowable.validation.ValidationError; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | | /** |
| | | * 模åç®¡ç æå¡å±å®ç° |
| | | * |
| | | * @author may |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActModelServiceImpl implements IActModelService { |
| | | |
| | | private final RepositoryService repositoryService; |
| | | private final IWfNodeConfigService wfNodeConfigService; |
| | | private final IWfDefinitionConfigService wfDefinitionConfigService; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param modelBo 模ååæ° |
| | | * @return è¿åå页å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery) { |
| | | ModelQuery query = QueryUtils.modelQuery(); |
| | | if (StringUtils.isNotBlank(modelBo.getName())) { |
| | | query.modelNameLike("%" + modelBo.getName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getKey())) { |
| | | query.modelKey(modelBo.getKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(modelBo.getCategoryCode())) { |
| | | query.modelCategory(modelBo.getCategoryCode()); |
| | | } |
| | | query.orderByLastUpdateTime().desc(); |
| | | // å建æ¶é´éåºæå |
| | | query.orderByCreateTime().desc(); |
| | | // å页æ¥è¯¢ |
| | | List<Model> modelList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | // æ»è®°å½æ° |
| | | long total = query.count(); |
| | | TableDataInfo<Model> build = TableDataInfo.build(); |
| | | build.setRows(modelList); |
| | | build.setTotal(total); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æ¨¡å |
| | | * |
| | | * @param modelBo 模å请æ±å¯¹è±¡ |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean saveNewModel(ModelBo modelBo) { |
| | | try { |
| | | int version = 0; |
| | | String key = modelBo.getKey(); |
| | | String name = modelBo.getName(); |
| | | String description = modelBo.getDescription(); |
| | | String categoryCode = modelBo.getCategoryCode(); |
| | | String xml = modelBo.getXml(); |
| | | Model checkModel = QueryUtils.modelQuery().modelKey(key).singleResult(); |
| | | if (ObjectUtil.isNotNull(checkModel)) { |
| | | throw new ServiceException("模åkeyå·²åå¨ï¼"); |
| | | } |
| | | //åå§ç©ºç模å |
| | | Model model = repositoryService.newModel(); |
| | | model.setKey(key); |
| | | model.setName(name); |
| | | model.setVersion(version); |
| | | model.setCategory(categoryCode); |
| | | model.setMetaInfo(description); |
| | | model.setTenantId(TenantHelper.getTenantId()); |
| | | //ä¿ååå§åçæ¨¡ååºæ¬ä¿¡æ¯æ°æ® |
| | | repositoryService.saveModel(model); |
| | | repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(xml)); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¨¡å |
| | | * |
| | | * @param id 模åid |
| | | * @return æ¨¡åæ°æ® |
| | | */ |
| | | @Override |
| | | public ModelVo getInfo(String id) { |
| | | ModelVo modelVo = new ModelVo(); |
| | | Model model = repositoryService.getModel(id); |
| | | if (model != null) { |
| | | try { |
| | | byte[] modelEditorSource = repositoryService.getModelEditorSource(model.getId()); |
| | | modelVo.setXml(StrUtil.utf8Str(modelEditorSource)); |
| | | modelVo.setId(model.getId()); |
| | | modelVo.setKey(model.getKey()); |
| | | modelVo.setName(model.getName()); |
| | | modelVo.setCategoryCode(model.getCategory()); |
| | | modelVo.setDescription(model.getMetaInfo()); |
| | | return modelVo; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | return modelVo; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æ¨¡åä¿¡æ¯ |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public boolean update(ModelBo modelBo) { |
| | | try { |
| | | Model model = repositoryService.getModel(modelBo.getId()); |
| | | List<Model> list = QueryUtils.modelQuery().modelKey(modelBo.getKey()).list(); |
| | | list.stream().filter(e -> !e.getId().equals(model.getId())).findFirst().ifPresent(e -> { |
| | | throw new ServiceException("模åKEYå·²åå¨ï¼"); |
| | | }); |
| | | model.setCategory(modelBo.getCategoryCode()); |
| | | model.setMetaInfo(modelBo.getDescription()); |
| | | repositoryService.saveModel(model); |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * ç¼è¾æ¨¡åXML |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean editModelXml(ModelBo modelBo) { |
| | | try { |
| | | String xml = modelBo.getXml(); |
| | | String svg = modelBo.getSvg(); |
| | | String modelId = modelBo.getId(); |
| | | String key = modelBo.getKey(); |
| | | String name = modelBo.getName(); |
| | | BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xml); |
| | | ModelUtils.checkBpmnModel(bpmnModel); |
| | | Model model = repositoryService.getModel(modelId); |
| | | List<Model> list = QueryUtils.modelQuery().modelKey(key).list(); |
| | | list.stream().filter(e -> !e.getId().equals(model.getId())).findFirst().ifPresent(e -> { |
| | | throw new ServiceException("模åKEYå·²åå¨ï¼"); |
| | | }); |
| | | // æ ¡éªkeyå½åè§è |
| | | if (!Validator.isMatchRegex(FlowConstant.MODEL_KEY_PATTERN, key)) { |
| | | throw new ServiceException("æ¨¡åæ è¯KEYåªè½å符æè
ä¸å线å¼å¤´ï¼"); |
| | | } |
| | | model.setKey(key); |
| | | model.setName(name); |
| | | model.setVersion(model.getVersion() + 1); |
| | | repositoryService.saveModel(model); |
| | | repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(xml)); |
| | | // 转æ¢å¾ç |
| | | InputStream svgStream = new ByteArrayInputStream(StrUtil.utf8Bytes(svg)); |
| | | TranscoderInput input = new TranscoderInput(svgStream); |
| | | |
| | | PNGTranscoder transcoder = new PNGTranscoder(); |
| | | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| | | TranscoderOutput output = new TranscoderOutput(outStream); |
| | | |
| | | transcoder.transcode(input, output); |
| | | final byte[] result = outStream.toByteArray(); |
| | | repositoryService.addModelEditorSourceExtra(model.getId(), result); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 模åé¨ç½² |
| | | * |
| | | * @param id 模åid |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean modelDeploy(String id) { |
| | | try { |
| | | // æ¥è¯¢æµç¨å®ä¹æ¨¡åxml |
| | | byte[] xmlBytes = repositoryService.getModelEditorSource(id); |
| | | if (ArrayUtil.isEmpty(xmlBytes)) { |
| | | throw new ServiceException("æ¨¡åæ°æ®ä¸ºç©ºï¼è¯·å
设计æµç¨å®ä¹æ¨¡åï¼åè¿è¡é¨ç½²ï¼"); |
| | | } |
| | | if (JSONUtil.isTypeJSON(new String(xmlBytes, StandardCharsets.UTF_8))) { |
| | | byte[] bytes = ModelUtils.bpmnJsonToXmlBytes(xmlBytes); |
| | | if (ArrayUtil.isEmpty(bytes)) { |
| | | throw new ServiceException("模åä¸è½ä¸ºç©ºï¼è¯·è³å°è®¾è®¡ä¸æ¡ä¸»çº¿æµç¨ï¼"); |
| | | } |
| | | } |
| | | BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xmlBytes); |
| | | // æ ¡éªæ¨¡å |
| | | ModelUtils.checkBpmnModel(bpmnModel); |
| | | List<ValidationError> validationErrors = repositoryService.validateProcess(bpmnModel); |
| | | if (CollUtil.isNotEmpty(validationErrors)) { |
| | | String errorMsg = validationErrors.stream().map(ValidationError::getProblem).distinct().collect(Collectors.joining(",")); |
| | | throw new ServiceException(errorMsg); |
| | | } |
| | | // æ¥è¯¢æ¨¡åçåºæ¬ä¿¡æ¯ |
| | | Model model = repositoryService.getModel(id); |
| | | ProcessDefinition processDefinition = QueryUtils.definitionQuery().processDefinitionKey(model.getKey()).latestVersion().singleResult(); |
| | | // xmlèµæºçåç§° ï¼å¯¹åºact_ge_bytearray表ä¸çname_åæ®µ |
| | | String processName = model.getName() + ".bpmn20.xml"; |
| | | // è°ç¨é¨ç½²ç¸å
³çapiæ¹æ³è¿è¡é¨ç½²æµç¨å®ä¹ |
| | | Deployment deployment = repositoryService.createDeployment() |
| | | // é¨ç½²åç§° |
| | | .name(model.getName()) |
| | | // é¨ç½²æ è¯key |
| | | .key(model.getKey()) |
| | | // é¨ç½²æµç¨åç±» |
| | | .category(model.getCategory()) |
| | | // bpmn20.xmlèµæº |
| | | .addBytes(processName, xmlBytes) |
| | | // ç§æ·id |
| | | .tenantId(TenantHelper.getTenantId()) |
| | | .deploy(); |
| | | |
| | | // æ´æ° é¨ç½²id å°æµç¨å®ä¹æ¨¡åæ°æ®è¡¨ä¸ |
| | | model.setDeploymentId(deployment.getId()); |
| | | repositoryService.saveModel(model); |
| | | // æ´æ°åç±» |
| | | ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult(); |
| | | repositoryService.setProcessDefinitionCategory(definition.getId(), model.getCategory()); |
| | | //æ´æ°æµç¨å®ä¹é
ç½® |
| | | if (processDefinition != null) { |
| | | WfDefinitionConfigVo definitionVo = wfDefinitionConfigService.getByDefId(processDefinition.getId()); |
| | | if (definitionVo != null) { |
| | | wfDefinitionConfigService.deleteByDefIds(Collections.singletonList(processDefinition.getId())); |
| | | WfDefinitionConfigBo wfFormDefinition = new WfDefinitionConfigBo(); |
| | | wfFormDefinition.setDefinitionId(definition.getId()); |
| | | wfFormDefinition.setProcessKey(definition.getKey()); |
| | | wfFormDefinition.setTableName(definitionVo.getTableName()); |
| | | wfFormDefinition.setVersion(definition.getVersion()); |
| | | wfFormDefinition.setRemark(definitionVo.getRemark()); |
| | | wfDefinitionConfigService.saveOrUpdate(wfFormDefinition); |
| | | } |
| | | } |
| | | //æ´æ°æµç¨èç¹é
置表å |
| | | List<UserTask> userTasks = ModelUtils.getUserTaskFlowElements(definition.getId()); |
| | | UserTask applyUserTask = ModelUtils.getApplyUserTask(definition.getId()); |
| | | List<WfNodeConfig> wfNodeConfigList = new ArrayList<>(); |
| | | for (UserTask userTask : userTasks) { |
| | | if (StringUtils.isNotBlank(userTask.getFormKey()) && userTask.getFormKey().contains(StrUtil.COLON)) { |
| | | WfNodeConfig wfNodeConfig = new WfNodeConfig(); |
| | | wfNodeConfig.setNodeId(userTask.getId()); |
| | | wfNodeConfig.setNodeName(userTask.getName()); |
| | | wfNodeConfig.setDefinitionId(definition.getId()); |
| | | String[] split = userTask.getFormKey().split(StrUtil.COLON); |
| | | wfNodeConfig.setFormType(split[0]); |
| | | wfNodeConfig.setFormId(Long.valueOf(split[1])); |
| | | wfNodeConfig.setApplyUserTask(applyUserTask.getId().equals(userTask.getId()) ? FlowConstant.TRUE : FlowConstant.FALSE); |
| | | wfNodeConfigList.add(wfNodeConfig); |
| | | } |
| | | } |
| | | if (CollUtil.isNotEmpty(wfNodeConfigList)) { |
| | | wfNodeConfigService.saveOrUpdate(wfNodeConfigList); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¯¼åºæ¨¡åzipå缩å
|
| | | * |
| | | * @param modelIds 模åid |
| | | * @param response ç¸åº |
| | | */ |
| | | @Override |
| | | public void exportZip(List<String> modelIds, HttpServletResponse response) { |
| | | try (ZipOutputStream zos = ZipUtil.getZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8)) { |
| | | // å缩å
æä»¶å |
| | | String zipName = "模åä¸åå¨"; |
| | | // æ¥è¯¢æ¨¡ååºæ¬ä¿¡æ¯ |
| | | for (String modelId : modelIds) { |
| | | Model model = repositoryService.getModel(modelId); |
| | | byte[] xmlBytes = repositoryService.getModelEditorSource(modelId); |
| | | if (ObjectUtil.isNotNull(model)) { |
| | | if (JSONUtil.isTypeJSON(new String(xmlBytes, StandardCharsets.UTF_8)) && ArrayUtil.isEmpty(ModelUtils.bpmnJsonToXmlBytes(xmlBytes))) { |
| | | zipName = "模åä¸è½ä¸ºç©ºï¼è¯·è³å°è®¾è®¡ä¸æ¡ä¸»çº¿æµç¨ï¼"; |
| | | zos.putNextEntry(new ZipEntry(zipName + ".txt")); |
| | | zos.write(zipName.getBytes(StandardCharsets.UTF_8)); |
| | | } else if (ArrayUtil.isEmpty(xmlBytes)) { |
| | | zipName = "æ¨¡åæ°æ®ä¸ºç©ºï¼è¯·å
设计æµç¨å®ä¹æ¨¡åï¼åè¿è¡é¨ç½²ï¼"; |
| | | zos.putNextEntry(new ZipEntry(zipName + ".txt")); |
| | | zos.write(zipName.getBytes(StandardCharsets.UTF_8)); |
| | | } else { |
| | | String fileName = model.getName() + "-" + model.getKey(); |
| | | // å缩å
æä»¶å |
| | | zipName = fileName + ".zip"; |
| | | // å°xmlæ·»å å°å缩å
ä¸(æå®xmlæä»¶åï¼è¯·åæµç¨.bpmn20.xml |
| | | zos.putNextEntry(new ZipEntry(fileName + ".bpmn20.xml")); |
| | | zos.write(xmlBytes); |
| | | } |
| | | } |
| | | } |
| | | response.setHeader("Content-Disposition", |
| | | "attachment; filename=" + URLEncoder.encode(zipName, StandardCharsets.UTF_8) + ".zip"); |
| | | response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); |
| | | // å·åºååºæµ |
| | | response.flushBuffer(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤å¶æ¨¡å |
| | | * |
| | | * @param modelBo æ¨¡åæ°æ® |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean copyModel(ModelBo modelBo) { |
| | | try { |
| | | String key = modelBo.getKey(); |
| | | if (StringUtils.isNotBlank(key)) { |
| | | // æ¥è¯¢æ¨¡å |
| | | Model model = repositoryService.createModelQuery().modelId(modelBo.getId()).singleResult(); |
| | | if (ObjectUtil.isNotNull(model)) { |
| | | byte[] modelEditorSource = repositoryService.getModelEditorSource(model.getId()); |
| | | List<Model> list = QueryUtils.modelQuery().modelKey(key).list(); |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | throw new ServiceException("模åKEYå·²åå¨ï¼"); |
| | | } |
| | | // æ ¡éªkeyå½åè§è |
| | | if (!Validator.isMatchRegex(FlowConstant.MODEL_KEY_PATTERN, key)) { |
| | | throw new ServiceException("æ¨¡åæ è¯KEYåªè½å符æè
ä¸å线å¼å¤´ï¼"); |
| | | } |
| | | // å¤å¶æ¨¡åæ°æ® |
| | | Model newModel = repositoryService.newModel(); |
| | | newModel.setKey(modelBo.getKey()); |
| | | newModel.setName(modelBo.getName()); |
| | | newModel.setCategory(modelBo.getCategoryCode()); |
| | | newModel.setVersion(1); |
| | | newModel.setMetaInfo(modelBo.getDescription()); |
| | | newModel.setTenantId(TenantHelper.getTenantId()); |
| | | String xml = StrUtil.utf8Str(modelEditorSource); |
| | | BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xml); |
| | | Process mainProcess = bpmnModel.getMainProcess(); |
| | | mainProcess.setId(modelBo.getKey()); |
| | | mainProcess.setName(modelBo.getName()); |
| | | byte[] xmlBytes = new BpmnXMLConverter().convertToXML(bpmnModel); |
| | | repositoryService.saveModel(newModel); |
| | | repositoryService.addModelEditorSource(newModel.getId(), xmlBytes); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | return true; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.io.FileUtil; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.SneakyThrows; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.workflow.common.constant.FlowConstant; |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | import org.dromara.workflow.domain.WfDefinitionConfig; |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.workflow.domain.bo.ProcessDefinitionBo; |
| | | import org.dromara.workflow.domain.bo.WfDefinitionConfigBo; |
| | | import org.dromara.workflow.domain.vo.ProcessDefinitionVo; |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.workflow.mapper.WfDefinitionConfigMapper; |
| | | import org.dromara.workflow.service.IActProcessDefinitionService; |
| | | import org.dromara.workflow.service.IWfCategoryService; |
| | | import org.dromara.workflow.service.IWfDefinitionConfigService; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | | import org.dromara.workflow.utils.ModelUtils; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.bpmn.model.UserTask; |
| | | import org.flowable.engine.ProcessMigrationService; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.impl.bpmn.deployer.ResourceNameUtil; |
| | | import org.flowable.engine.repository.*; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipInputStream; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹ æå¡å±å®ç° |
| | | * |
| | | * @author may |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionService { |
| | | |
| | | private final RepositoryService repositoryService; |
| | | private final ProcessMigrationService processMigrationService; |
| | | private final IWfCategoryService wfCategoryService; |
| | | private final IWfDefinitionConfigService wfDefinitionConfigService; |
| | | private final WfDefinitionConfigMapper wfDefinitionConfigMapper; |
| | | private final IWfNodeConfigService wfNodeConfigService; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢ |
| | | * |
| | | * @param bo åæ° |
| | | * @return è¿åå页å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo bo, PageQuery pageQuery) { |
| | | ProcessDefinitionQuery query = QueryUtils.definitionQuery(); |
| | | if (StringUtils.isNotEmpty(bo.getKey())) { |
| | | query.processDefinitionKey(bo.getKey()); |
| | | } |
| | | if (StringUtils.isNotEmpty(bo.getCategoryCode())) { |
| | | query.processDefinitionCategory(bo.getCategoryCode()); |
| | | } |
| | | if (StringUtils.isNotEmpty(bo.getName())) { |
| | | query.processDefinitionNameLike("%" + bo.getName() + "%"); |
| | | } |
| | | query.orderByDeploymentId().desc(); |
| | | // å页æ¥è¯¢ |
| | | List<ProcessDefinitionVo> processDefinitionVoList = new ArrayList<>(); |
| | | List<ProcessDefinition> definitionList = query.latestVersion().listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | List<Deployment> deploymentList = null; |
| | | if (CollUtil.isNotEmpty(definitionList)) { |
| | | List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId); |
| | | deploymentList = QueryUtils.deploymentQuery(deploymentIds).list(); |
| | | } |
| | | if (CollUtil.isNotEmpty(definitionList)) { |
| | | List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId); |
| | | List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids); |
| | | for (ProcessDefinition processDefinition : definitionList) { |
| | | ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class); |
| | | if (CollUtil.isNotEmpty(deploymentList)) { |
| | | // é¨ç½²æ¶é´ |
| | | deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> { |
| | | processDefinitionVo.setDeploymentTime(e.getDeploymentTime()); |
| | | }); |
| | | } |
| | | if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) { |
| | | wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo); |
| | | } |
| | | processDefinitionVoList.add(processDefinitionVo); |
| | | } |
| | | } |
| | | // æ»è®°å½æ° |
| | | long total = query.count(); |
| | | TableDataInfo<ProcessDefinitionVo> build = TableDataInfo.build(); |
| | | build.setRows(processDefinitionVoList); |
| | | build.setTotal(total); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å岿µç¨å®ä¹å表 |
| | | * |
| | | * @param key æµç¨å®ä¹key |
| | | */ |
| | | @Override |
| | | public List<ProcessDefinitionVo> getListByKey(String key) { |
| | | List<ProcessDefinitionVo> processDefinitionVoList = new ArrayList<>(); |
| | | ProcessDefinitionQuery query = QueryUtils.definitionQuery(); |
| | | List<ProcessDefinition> definitionList = query.processDefinitionKey(key).list(); |
| | | List<Deployment> deploymentList = null; |
| | | if (CollUtil.isNotEmpty(definitionList)) { |
| | | List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId); |
| | | deploymentList = QueryUtils.deploymentQuery(deploymentIds).list(); |
| | | } |
| | | if (CollUtil.isNotEmpty(definitionList)) { |
| | | List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId); |
| | | List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids); |
| | | for (ProcessDefinition processDefinition : definitionList) { |
| | | ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class); |
| | | if (CollUtil.isNotEmpty(deploymentList)) { |
| | | // é¨ç½²æ¶é´ |
| | | deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> { |
| | | processDefinitionVo.setDeploymentTime(e.getDeploymentTime()); |
| | | }); |
| | | if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) { |
| | | wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo); |
| | | } |
| | | } |
| | | processDefinitionVoList.add(processDefinitionVo); |
| | | } |
| | | } |
| | | return CollUtil.reverse(processDefinitionVoList); |
| | | } |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹å¾ç |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @SneakyThrows |
| | | @Override |
| | | public String definitionImage(String processDefinitionId) { |
| | | InputStream inputStream = repositoryService.getProcessDiagram(processDefinitionId); |
| | | return Base64.encode(IoUtil.readBytes(inputStream)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥çæµç¨å®ä¹xmlæä»¶ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @Override |
| | | public String definitionXml(String processDefinitionId) { |
| | | StringBuilder xml = new StringBuilder(); |
| | | ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId); |
| | | InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName()); |
| | | xml.append(IoUtil.read(inputStream, StandardCharsets.UTF_8)); |
| | | return xml.toString(); |
| | | } |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¹ |
| | | * |
| | | * @param deploymentIds é¨ç½²id |
| | | * @param processDefinitionIds æµç¨å®ä¹id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteDeployment(List<String> deploymentIds, List<String> processDefinitionIds) { |
| | | try { |
| | | List<HistoricProcessInstance> historicProcessInstances = QueryUtils.hisInstanceQuery().deploymentIdIn(deploymentIds).list(); |
| | | if (CollUtil.isNotEmpty(historicProcessInstances)) { |
| | | Set<String> defIds = StreamUtils.toSet(historicProcessInstances, HistoricProcessInstance::getProcessDefinitionId); |
| | | List<ProcessDefinition> processDefinitions = QueryUtils.definitionQuery().processDefinitionIds(defIds).list(); |
| | | if (CollUtil.isNotEmpty(processDefinitions)) { |
| | | Set<String> keys = StreamUtils.toSet(processDefinitions, ProcessDefinition::getKey); |
| | | throw new ServiceException("å½åã" + String.join(",", keys) + "ãæµç¨å®ä¹å·²è¢«ä½¿ç¨ä¸å¯å é¤ï¼"); |
| | | } |
| | | } |
| | | //å 餿µç¨å®ä¹ |
| | | for (String deploymentId : deploymentIds) { |
| | | repositoryService.deleteDeployment(deploymentId); |
| | | } |
| | | //å 餿µç¨å®ä¹é
ç½® |
| | | wfDefinitionConfigService.deleteByDefIds(processDefinitionIds); |
| | | //å é¤èç¹é
ç½® |
| | | wfNodeConfigService.deleteByDefIds(processDefinitionIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¿æ´»æè
æèµ·æµç¨å®ä¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @Override |
| | | public boolean updateDefinitionState(String processDefinitionId) { |
| | | try { |
| | | ProcessDefinition processDefinition = QueryUtils.definitionQuery() |
| | | .processDefinitionId(processDefinitionId).singleResult(); |
| | | //å°å½å为æèµ·ç¶ææ´æ°ä¸ºæ¿æ´»ç¶æ |
| | | //åæ°è¯´æï¼åæ°1ï¼æµç¨å®ä¹id,åæ°2ï¼æ¯å¦æ¿æ´»ï¼trueæ¯å¦çº§èå¯¹åºæµç¨å®ä¾ï¼æ¿æ´»äºåå¯¹åºæµç¨å®ä¾é½å¯ä»¥å®¡æ¹ï¼ï¼ |
| | | //åæ°3ï¼ä»ä¹æ¶åæ¿æ´»ï¼å¦æä¸ºnullåç«å³æ¿æ´»ï¼å¦æä¸ºå
·ä½æ¶é´åå°è¾¾æ¤æ¶é´åæ¿æ´» |
| | | if (processDefinition.isSuspended()) { |
| | | repositoryService.activateProcessDefinitionById(processDefinitionId, true, null); |
| | | } else { |
| | | repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException("æä½å¤±è´¥:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è¿ç§»æµç¨å®ä¹ |
| | | * |
| | | * @param currentProcessDefinitionId å½åæµç¨å®ä¹id |
| | | * @param fromProcessDefinitionId éè¦è¿ç§»å°çæµç¨å®ä¹id |
| | | */ |
| | | |
| | | @Override |
| | | public boolean migrationDefinition(String currentProcessDefinitionId, String fromProcessDefinitionId) { |
| | | try { |
| | | // è¿ç§»éªè¯ |
| | | boolean migrationValid = processMigrationService.createProcessInstanceMigrationBuilder() |
| | | .migrateToProcessDefinition(currentProcessDefinitionId) |
| | | .validateMigrationOfProcessInstances(fromProcessDefinitionId) |
| | | .isMigrationValid(); |
| | | if (!migrationValid) { |
| | | throw new ServiceException("æµç¨å®ä¹å·®å¼è¿å¤§æ æ³è¿ç§»ï¼è¯·ä¿®æ¹æµç¨å¾"); |
| | | } |
| | | // å·²ç»æçæµç¨å®ä¾ä¸ä¼è¿ç§» |
| | | processMigrationService.createProcessInstanceMigrationBuilder() |
| | | .migrateToProcessDefinition(currentProcessDefinitionId) |
| | | .migrateProcessInstances(fromProcessDefinitionId); |
| | | return true; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æµç¨å®ä¹è½¬æ¢ä¸ºæ¨¡å |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | @Override |
| | | public boolean convertToModel(String processDefinitionId) { |
| | | ProcessDefinition pd = QueryUtils.definitionQuery() |
| | | .processDefinitionId(processDefinitionId).singleResult(); |
| | | InputStream inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getResourceName()); |
| | | ModelQuery query = QueryUtils.modelQuery(); |
| | | Model model = query.modelKey(pd.getKey()).singleResult(); |
| | | try { |
| | | if (ObjectUtil.isNotNull(model)) { |
| | | repositoryService.addModelEditorSource(model.getId(), IoUtil.readBytes(inputStream)); |
| | | } else { |
| | | Model modelData = repositoryService.newModel(); |
| | | modelData.setKey(pd.getKey()); |
| | | modelData.setName(pd.getName()); |
| | | modelData.setTenantId(pd.getTenantId()); |
| | | repositoryService.saveModel(modelData); |
| | | repositoryService.addModelEditorSource(modelData.getId(), IoUtil.readBytes(inputStream)); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿zipæxmlé¨ç½²æµç¨å®ä¹ |
| | | * |
| | | * @param file æä»¶ |
| | | * @param categoryCode åç±» |
| | | */ |
| | | @SneakyThrows |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deployByFile(MultipartFile file, String categoryCode) { |
| | | |
| | | WfCategory wfCategory = wfCategoryService.queryByCategoryCode(categoryCode); |
| | | if (wfCategory == null) { |
| | | throw new ServiceException("æµç¨åç±»ä¸åå¨"); |
| | | } |
| | | // æä»¶åç¼å |
| | | String suffix = FileUtil.extName(file.getOriginalFilename()); |
| | | InputStream inputStream = file.getInputStream(); |
| | | if (FlowConstant.ZIP.equalsIgnoreCase(suffix)) { |
| | | ZipInputStream zipInputStream = null; |
| | | try { |
| | | zipInputStream = new ZipInputStream(inputStream); |
| | | ZipEntry zipEntry; |
| | | while ((zipEntry = zipInputStream.getNextEntry()) != null) { |
| | | String filename = zipEntry.getName(); |
| | | String[] splitFilename = filename.substring(0, filename.lastIndexOf(".")).split("-"); |
| | | //æµç¨åç§° |
| | | String processName = splitFilename[0]; |
| | | //æµç¨key |
| | | String processKey = splitFilename[1]; |
| | | ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult(); |
| | | DeploymentBuilder builder = repositoryService.createDeployment(); |
| | | Deployment deployment = builder.addInputStream(filename, zipInputStream) |
| | | .tenantId(TenantHelper.getTenantId()) |
| | | .name(processName).key(processKey).category(categoryCode).deploy(); |
| | | ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult(); |
| | | repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode); |
| | | setWfConfig(oldProcessDefinition, definition); |
| | | zipInputStream.closeEntry(); |
| | | } |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } finally { |
| | | if (zipInputStream != null) { |
| | | zipInputStream.close(); |
| | | } |
| | | } |
| | | //åå§åé
ç½®æ°æ®ï¼demo使ç¨ï¼ä¸ç¨å¯å é¤ï¼ |
| | | initWfDefConfig(); |
| | | } else { |
| | | String originalFilename = file.getOriginalFilename(); |
| | | String bpmnResourceSuffix = ResourceNameUtil.BPMN_RESOURCE_SUFFIXES[0]; |
| | | if (originalFilename.contains(bpmnResourceSuffix)) { |
| | | // æä»¶å = æµç¨åç§°-æµç¨key |
| | | String[] splitFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")).split("-"); |
| | | if (splitFilename.length < 2) { |
| | | throw new ServiceException("æä»¶å = æµç¨åç§°-æµç¨KEY"); |
| | | } |
| | | //æµç¨åç§° |
| | | String processName = splitFilename[0]; |
| | | //æµç¨key |
| | | String processKey = splitFilename[1]; |
| | | ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult(); |
| | | DeploymentBuilder builder = repositoryService.createDeployment(); |
| | | Deployment deployment = builder.addInputStream(originalFilename, inputStream) |
| | | .tenantId(TenantHelper.getTenantId()) |
| | | .name(processName).key(processKey).category(categoryCode).deploy(); |
| | | // æ´æ°åç±» |
| | | ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult(); |
| | | repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode); |
| | | setWfConfig(oldProcessDefinition, definition); |
| | | } else { |
| | | throw new ServiceException("æä»¶ç±»åä¸ä¼ é误ï¼"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * åå§åé
ç½®æ°æ®ï¼demo使ç¨ï¼ä¸ç¨å¯å é¤ï¼ |
| | | */ |
| | | private void initWfDefConfig() { |
| | | List<WfDefinitionConfig> wfDefinitionConfigs = wfDefinitionConfigMapper.selectList(); |
| | | if (CollUtil.isEmpty(wfDefinitionConfigs)) { |
| | | ProcessDefinition processDefinition = QueryUtils.definitionQuery().processDefinitionKey("leave1").latestVersion().singleResult(); |
| | | if (processDefinition != null) { |
| | | WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo(); |
| | | wfDefinitionConfigBo.setDefinitionId(processDefinition.getId()); |
| | | wfDefinitionConfigBo.setProcessKey(processDefinition.getKey()); |
| | | wfDefinitionConfigBo.setTableName("test_leave"); |
| | | wfDefinitionConfigBo.setVersion(processDefinition.getVersion()); |
| | | wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 设置表åå
容 |
| | | * |
| | | * @param oldProcessDefinition é¨ç½²åææ°æµç¨å®ä¹ |
| | | * @param definition é¨ç½²åææ°æµç¨å®ä¹ |
| | | */ |
| | | private void setWfConfig(ProcessDefinition oldProcessDefinition, ProcessDefinition definition) { |
| | | //æ´æ°æµç¨å®ä¹è¡¨å |
| | | if (oldProcessDefinition != null) { |
| | | WfDefinitionConfigVo definitionVo = wfDefinitionConfigService.getByDefId(oldProcessDefinition.getId()); |
| | | if (definitionVo != null) { |
| | | wfDefinitionConfigService.deleteByDefIds(Collections.singletonList(oldProcessDefinition.getId())); |
| | | WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo(); |
| | | wfDefinitionConfigBo.setDefinitionId(definition.getId()); |
| | | wfDefinitionConfigBo.setProcessKey(definition.getKey()); |
| | | wfDefinitionConfigBo.setTableName(definitionVo.getTableName()); |
| | | wfDefinitionConfigBo.setVersion(definition.getVersion()); |
| | | wfDefinitionConfigBo.setRemark(definitionVo.getRemark()); |
| | | wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo); |
| | | } |
| | | } |
| | | //æ´æ°æµç¨èç¹é
置表å |
| | | List<UserTask> userTasks = ModelUtils.getUserTaskFlowElements(definition.getId()); |
| | | UserTask applyUserTask = ModelUtils.getApplyUserTask(definition.getId()); |
| | | List<WfNodeConfig> wfNodeConfigList = new ArrayList<>(); |
| | | for (UserTask userTask : userTasks) { |
| | | if (StringUtils.isNotBlank(userTask.getFormKey()) && userTask.getFormKey().contains(StrUtil.COLON)) { |
| | | WfNodeConfig wfNodeConfig = new WfNodeConfig(); |
| | | wfNodeConfig.setNodeId(userTask.getId()); |
| | | wfNodeConfig.setNodeName(userTask.getName()); |
| | | wfNodeConfig.setDefinitionId(definition.getId()); |
| | | String[] split = userTask.getFormKey().split(StrUtil.COLON); |
| | | wfNodeConfig.setFormType(split[0]); |
| | | wfNodeConfig.setFormId(Long.valueOf(split[1])); |
| | | wfNodeConfig.setApplyUserTask(applyUserTask.getId().equals(userTask.getId()) ? FlowConstant.TRUE : FlowConstant.FALSE); |
| | | wfNodeConfigList.add(wfNodeConfig); |
| | | } |
| | | } |
| | | if (CollUtil.isNotEmpty(wfNodeConfigList)) { |
| | | wfNodeConfigService.saveOrUpdate(wfNodeConfigList); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.workflow.common.constant.FlowConstant; |
| | | import org.dromara.workflow.common.enums.BusinessStatusEnum; |
| | | import org.dromara.workflow.common.enums.TaskStatusEnum; |
| | | import org.dromara.workflow.domain.ActHiProcinst; |
| | | import org.dromara.workflow.domain.bo.ProcessInstanceBo; |
| | | import org.dromara.workflow.domain.bo.ProcessInvalidBo; |
| | | import org.dromara.workflow.domain.bo.TaskUrgingBo; |
| | | import org.dromara.workflow.domain.vo.*; |
| | | import org.dromara.workflow.flowable.CustomDefaultProcessDiagramGenerator; |
| | | import org.dromara.workflow.flowable.cmd.DeleteExecutionCmd; |
| | | import org.dromara.workflow.flowable.cmd.ExecutionChildByExecutionIdCmd; |
| | | import org.dromara.workflow.flowable.strategy.FlowEventStrategy; |
| | | import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler; |
| | | import org.dromara.workflow.service.IActHiProcinstService; |
| | | import org.dromara.workflow.service.IActProcessInstanceService; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | | import org.dromara.workflow.service.IWfTaskBackNodeService; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.dromara.workflow.utils.WorkflowUtils; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.engine.*; |
| | | import org.flowable.engine.history.HistoricActivityInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstanceQuery; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.flowable.engine.runtime.ProcessInstance; |
| | | import org.flowable.engine.runtime.ProcessInstanceQuery; |
| | | import org.flowable.engine.task.Attachment; |
| | | import org.flowable.engine.task.Comment; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.awt.*; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * æµç¨å®ä¾ æå¡å±å®ç° |
| | | * |
| | | * @author may |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActProcessInstanceServiceImpl implements IActProcessInstanceService { |
| | | |
| | | private final RepositoryService repositoryService; |
| | | private final RuntimeService runtimeService; |
| | | private final HistoryService historyService; |
| | | private final TaskService taskService; |
| | | private final IActHiProcinstService actHiProcinstService; |
| | | private final ManagementService managementService; |
| | | private final FlowEventStrategy flowEventStrategy; |
| | | private final IWfTaskBackNodeService wfTaskBackNodeService; |
| | | private final IWfNodeConfigService wfNodeConfigService; |
| | | |
| | | @Value("${flowable.activity-font-name}") |
| | | private String activityFontName; |
| | | |
| | | @Value("${flowable.label-font-name}") |
| | | private String labelFontName; |
| | | |
| | | @Value("${flowable.annotation-font-name}") |
| | | private String annotationFontName; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢æ£å¨è¿è¡çæµç¨å®ä¾ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | List<ProcessInstanceVo> list = new ArrayList<>(); |
| | | ProcessInstanceQuery query = QueryUtils.instanceQuery(); |
| | | if (StringUtils.isNotBlank(bo.getName())) { |
| | | query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getKey())) { |
| | | query.processDefinitionKey(bo.getKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getStartUserId())) { |
| | | query.startedBy(bo.getStartUserId()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getBusinessKey())) { |
| | | query.processInstanceBusinessKey(bo.getBusinessKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getCategoryCode())) { |
| | | query.processDefinitionCategory(bo.getCategoryCode()); |
| | | } |
| | | query.orderByStartTime().desc(); |
| | | List<ProcessInstance> processInstances = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | for (ProcessInstance processInstance : processInstances) { |
| | | ProcessInstanceVo processInstanceVo = BeanUtil.toBean(processInstance, ProcessInstanceVo.class); |
| | | processInstanceVo.setIsSuspended(processInstance.isSuspended()); |
| | | processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstance.getBusinessStatus())); |
| | | list.add(processInstanceVo); |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | long count = query.count(); |
| | | TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build(); |
| | | build.setRows(list); |
| | | build.setTotal(count); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å·²ç»æçæµç¨å®ä¾ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | List<ProcessInstanceVo> list = new ArrayList<>(); |
| | | HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery() |
| | | .finished().orderByProcessInstanceEndTime().desc(); |
| | | if (StringUtils.isNotEmpty(bo.getName())) { |
| | | query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getKey())) { |
| | | query.processDefinitionKey(bo.getKey()); |
| | | } |
| | | if (StringUtils.isNotEmpty(bo.getStartUserId())) { |
| | | query.startedBy(bo.getStartUserId()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getBusinessKey())) { |
| | | query.processInstanceBusinessKey(bo.getBusinessKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getCategoryCode())) { |
| | | query.processDefinitionCategory(bo.getCategoryCode()); |
| | | } |
| | | List<HistoricProcessInstance> historicProcessInstances = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) { |
| | | ProcessInstanceVo processInstanceVo = BeanUtil.toBean(historicProcessInstance, ProcessInstanceVo.class); |
| | | processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(historicProcessInstance.getBusinessStatus())); |
| | | list.add(processInstanceVo); |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | long count = query.count(); |
| | | TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build(); |
| | | build.setRows(list); |
| | | build.setTotal(count); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @SneakyThrows |
| | | @Override |
| | | public String getHistoryImage(String processInstanceId) { |
| | | String processDefinitionId; |
| | | // è·åå½åçæµç¨å®ä¾ |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId).singleResult(); |
| | | // 妿æµç¨å·²ç»ç»æï¼åå¾å°ç»æèç¹ |
| | | if (Objects.isNull(processInstance)) { |
| | | HistoricProcessInstance pi = QueryUtils.hisInstanceQuery(processInstanceId).singleResult(); |
| | | processDefinitionId = pi.getProcessDefinitionId(); |
| | | } else { |
| | | // æ ¹æ®æµç¨å®ä¾IDè·å¾å½åå¤äºæ´»å¨ç¶æçActivityIdåé |
| | | ProcessInstance pi = QueryUtils.instanceQuery(processInstanceId).singleResult(); |
| | | processDefinitionId = pi.getProcessDefinitionId(); |
| | | } |
| | | |
| | | // è·å¾æ´»å¨çèç¹ |
| | | List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list(); |
| | | |
| | | List<String> highLightedFlows = new ArrayList<>(); |
| | | List<String> highLightedNodes = new ArrayList<>(); |
| | | //é«äº® |
| | | for (HistoricActivityInstance tempActivity : highLightedFlowList) { |
| | | if (FlowConstant.SEQUENCE_FLOW.equals(tempActivity.getActivityType())) { |
| | | //é«äº®çº¿ |
| | | highLightedFlows.add(tempActivity.getActivityId()); |
| | | } else { |
| | | //é«äº®èç¹ |
| | | if (tempActivity.getEndTime() == null) { |
| | | highLightedNodes.add(Color.RED.toString() + tempActivity.getActivityId()); |
| | | } else { |
| | | highLightedNodes.add(tempActivity.getActivityId()); |
| | | } |
| | | } |
| | | } |
| | | List<String> highLightedNodeList = new ArrayList<>(); |
| | | //è¿è¡ä¸çèç¹ |
| | | List<String> redNodeCollect = StreamUtils.filter(highLightedNodes, e -> e.contains(Color.RED.toString())); |
| | | //æé¤ä¸è¿è¡ä¸ç¸åçèç¹ |
| | | for (String nodeId : highLightedNodes) { |
| | | if (!nodeId.contains(Color.RED.toString()) && !redNodeCollect.contains(Color.RED + nodeId)) { |
| | | highLightedNodeList.add(nodeId); |
| | | } |
| | | } |
| | | highLightedNodeList.addAll(redNodeCollect); |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); |
| | | CustomDefaultProcessDiagramGenerator diagramGenerator = new CustomDefaultProcessDiagramGenerator(); |
| | | InputStream inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodeList, highLightedFlows, activityFontName, labelFontName, annotationFontName, null, 1.0, true); |
| | | return Base64.encode(IoUtil.readBytes(inputStream)); |
| | | } |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¾idè·åå岿µç¨å¾è¿è¡ä¸ï¼åå²çèç¹ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | public Map<String, Object> getHistoryList(String processInstanceId) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | List<Map<String, Object>> taskList = new ArrayList<>(); |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult(); |
| | | StringBuilder xml = new StringBuilder(); |
| | | ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId()); |
| | | // è·åèç¹ |
| | | List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list(); |
| | | for (HistoricActivityInstance tempActivity : highLightedFlowList) { |
| | | Map<String, Object> task = new HashMap<>(); |
| | | if (!FlowConstant.SEQUENCE_FLOW.equals(tempActivity.getActivityType()) && |
| | | !FlowConstant.PARALLEL_GATEWAY.equals(tempActivity.getActivityType()) && |
| | | !FlowConstant.EXCLUSIVE_GATEWAY.equals(tempActivity.getActivityType()) && |
| | | !FlowConstant.INCLUSIVE_GATEWAY.equals(tempActivity.getActivityType()) |
| | | ) { |
| | | task.put("key", tempActivity.getActivityId()); |
| | | task.put("completed", tempActivity.getEndTime() != null); |
| | | task.put("activityType", tempActivity.getActivityType()); |
| | | taskList.add(task); |
| | | } |
| | | } |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId).singleResult(); |
| | | if (processInstance != null) { |
| | | taskList = taskList.stream().filter(e -> !e.get("activityType").equals(FlowConstant.END_EVENT)).collect(Collectors.toList()); |
| | | } |
| | | //æ¥è¯¢åºè¿è¡ä¸èç¹ |
| | | List<Map<String, Object>> runtimeNodeList = taskList.stream().filter(e -> !(Boolean) e.get("completed")).collect(Collectors.toList()); |
| | | if (CollUtil.isNotEmpty(runtimeNodeList)) { |
| | | Iterator<Map<String, Object>> iterator = taskList.iterator(); |
| | | while (iterator.hasNext()) { |
| | | Map<String, Object> next = iterator.next(); |
| | | runtimeNodeList.stream().filter(t -> t.get("key").equals(next.get("key")) && (Boolean) next.get("completed")).findFirst().ifPresent(t -> iterator.remove()); |
| | | } |
| | | } |
| | | map.put("taskList", taskList); |
| | | List<ActHistoryInfoVo> historyTaskList = getHistoryTaskList(processInstanceId); |
| | | map.put("historyList", historyTaskList); |
| | | InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName()); |
| | | xml.append(IoUtil.read(inputStream, StandardCharsets.UTF_8)); |
| | | map.put("xml", xml.toString()); |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * è·ååå²ä»»å¡èç¹ä¿¡æ¯ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | private List<ActHistoryInfoVo> getHistoryTaskList(String processInstanceId) { |
| | | //æ¥è¯¢ä»»å¡åçè®°å½ |
| | | List<HistoricTaskInstance> list = QueryUtils.hisTaskInstanceQuery(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list(); |
| | | list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo)).reversed()); |
| | | List<ActHistoryInfoVo> actHistoryInfoVoList = new ArrayList<>(); |
| | | for (HistoricTaskInstance historicTaskInstance : list) { |
| | | ActHistoryInfoVo actHistoryInfoVo = new ActHistoryInfoVo(); |
| | | BeanUtils.copyProperties(historicTaskInstance, actHistoryInfoVo); |
| | | actHistoryInfoVo.setStatus(actHistoryInfoVo.getEndTime() == null ? "å¾
å¤ç" : "å·²å¤ç"); |
| | | if (ObjectUtil.isNotEmpty(historicTaskInstance.getDurationInMillis())) { |
| | | actHistoryInfoVo.setRunDuration(getDuration(historicTaskInstance.getDurationInMillis())); |
| | | } |
| | | actHistoryInfoVoList.add(actHistoryInfoVo); |
| | | } |
| | | List<ActHistoryInfoVo> historyInfoVoList = new ArrayList<>(); |
| | | Map<String, List<ActHistoryInfoVo>> groupByKey = StreamUtils.groupByKey(actHistoryInfoVoList, ActHistoryInfoVo::getTaskDefinitionKey); |
| | | for (Map.Entry<String, List<ActHistoryInfoVo>> entry : groupByKey.entrySet()) { |
| | | ActHistoryInfoVo historyInfoVo = new ActHistoryInfoVo(); |
| | | BeanUtils.copyProperties(entry.getValue().get(0), historyInfoVo); |
| | | actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() == null).findFirst() |
| | | .ifPresent(e -> { |
| | | historyInfoVo.setStatus("å¾
å¤ç"); |
| | | historyInfoVo.setStartTime(e.getStartTime()); |
| | | historyInfoVo.setEndTime(null); |
| | | historyInfoVo.setRunDuration(null); |
| | | if (ObjectUtil.isEmpty(e.getAssignee())) { |
| | | ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(e.getId()); |
| | | if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) { |
| | | historyInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr)); |
| | | } |
| | | } |
| | | }); |
| | | historyInfoVoList.add(historyInfoVo); |
| | | } |
| | | return historyInfoVoList; |
| | | } |
| | | |
| | | /** |
| | | * è·å审æ¹è®°å½ |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | public List<ActHistoryInfoVo> getHistoryRecord(String processInstanceId) { |
| | | // æ¥è¯¢ä»»å¡åçè®°å½ |
| | | List<HistoricTaskInstance> list = QueryUtils.hisTaskInstanceQuery(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list(); |
| | | list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo)).reversed()); |
| | | List<ActHistoryInfoVo> actHistoryInfoVoList = new ArrayList<>(); |
| | | List<Comment> processInstanceComments = taskService.getProcessInstanceComments(processInstanceId); |
| | | //éä»¶ |
| | | List<Attachment> attachmentList = taskService.getProcessInstanceAttachments(processInstanceId); |
| | | for (HistoricTaskInstance historicTaskInstance : list) { |
| | | ActHistoryInfoVo actHistoryInfoVo = new ActHistoryInfoVo(); |
| | | BeanUtils.copyProperties(historicTaskInstance, actHistoryInfoVo); |
| | | if (actHistoryInfoVo.getEndTime() == null) { |
| | | actHistoryInfoVo.setStatus(TaskStatusEnum.WAITING.getStatus()); |
| | | actHistoryInfoVo.setStatusName(TaskStatusEnum.WAITING.getDesc()); |
| | | } |
| | | if (CollUtil.isNotEmpty(processInstanceComments)) { |
| | | processInstanceComments.stream().filter(e -> e.getTaskId().equals(historicTaskInstance.getId())).findFirst().ifPresent(e -> { |
| | | actHistoryInfoVo.setComment(e.getFullMessage()); |
| | | actHistoryInfoVo.setStatus(e.getType()); |
| | | actHistoryInfoVo.setStatusName(TaskStatusEnum.findByStatus(e.getType())); |
| | | }); |
| | | } |
| | | if (ObjectUtil.isNotEmpty(historicTaskInstance.getDurationInMillis())) { |
| | | actHistoryInfoVo.setRunDuration(getDuration(historicTaskInstance.getDurationInMillis())); |
| | | } |
| | | //éä»¶ |
| | | if (CollUtil.isNotEmpty(attachmentList)) { |
| | | List<Attachment> attachments = attachmentList.stream().filter(e -> e.getTaskId().equals(historicTaskInstance.getId())).collect(Collectors.toList()); |
| | | if (CollUtil.isNotEmpty(attachments)) { |
| | | actHistoryInfoVo.setAttachmentList(attachments); |
| | | } |
| | | } |
| | | //设置人åid |
| | | if (ObjectUtil.isEmpty(historicTaskInstance.getAssignee())) { |
| | | ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(historicTaskInstance.getId()); |
| | | if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) { |
| | | actHistoryInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr)); |
| | | } |
| | | } |
| | | actHistoryInfoVoList.add(actHistoryInfoVo); |
| | | } |
| | | // 审æ¹è®°å½ |
| | | Map<String, List<ActHistoryInfoVo>> groupByKey = StreamUtils.groupByKey(actHistoryInfoVoList, ActHistoryInfoVo::getTaskDefinitionKey); |
| | | for (Map.Entry<String, List<ActHistoryInfoVo>> entry : groupByKey.entrySet()) { |
| | | ActHistoryInfoVo actHistoryInfoVo = BeanUtil.toBean(entry.getValue().get(0), ActHistoryInfoVo.class); |
| | | actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() != null).findFirst() |
| | | .ifPresent(e -> { |
| | | actHistoryInfoVo.setStatus("å·²å¤ç"); |
| | | actHistoryInfoVo.setStartTime(e.getStartTime()); |
| | | }); |
| | | actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() == null).findFirst() |
| | | .ifPresent(e -> { |
| | | actHistoryInfoVo.setStatus("å¾
å¤ç"); |
| | | actHistoryInfoVo.setStartTime(e.getStartTime()); |
| | | actHistoryInfoVo.setEndTime(null); |
| | | actHistoryInfoVo.setRunDuration(null); |
| | | }); |
| | | } |
| | | List<ActHistoryInfoVo> recordList = new ArrayList<>(); |
| | | // å¾
åç |
| | | recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() == null)); |
| | | // å·²åç |
| | | recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() != null)); |
| | | |
| | | return recordList; |
| | | } |
| | | |
| | | /** |
| | | * ä»»å¡å®ææ¶é´å¤ç |
| | | * |
| | | * @param time æ¶é´ |
| | | */ |
| | | private String getDuration(long time) { |
| | | |
| | | long day = time / (24 * 60 * 60 * 1000); |
| | | long hour = (time / (60 * 60 * 1000) - day * 24); |
| | | long minute = ((time / (60 * 1000)) - day * 24 * 60 - hour * 60); |
| | | long second = (time / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60); |
| | | |
| | | if (day > 0) { |
| | | return day + "天" + hour + "å°æ¶" + minute + "åé"; |
| | | } |
| | | if (hour > 0) { |
| | | return hour + "å°æ¶" + minute + "åé"; |
| | | } |
| | | if (minute > 0) { |
| | | return minute + "åé"; |
| | | } |
| | | if (second > 0) { |
| | | return second + "ç§"; |
| | | } else { |
| | | return 0 + "ç§"; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä½åºæµç¨å®ä¾ï¼ä¸ä¼å é¤åå²è®°å½(å é¤è¿è¡ä¸çå®ä¾) |
| | | * |
| | | * @param processInvalidBo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunInstance(ProcessInvalidBo processInvalidBo) { |
| | | try { |
| | | List<Task> list = QueryUtils.taskQuery(processInvalidBo.getProcessInstanceId()).list(); |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | | } |
| | | String deleteReason = LoginHelper.getLoginUser().getNickname() + "ä½åºäºå½åç³è¯·ï¼"; |
| | | if (StringUtils.isNotBlank(processInvalidBo.getDeleteReason())) { |
| | | deleteReason = LoginHelper.getLoginUser().getNickname() + "ä½åºçç±:" + processInvalidBo.getDeleteReason(); |
| | | } |
| | | for (Task task : StreamUtils.filter(list, e -> StringUtils.isBlank(e.getParentTaskId()))) { |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.INVALID.getStatus(), deleteReason); |
| | | } |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInvalidBo.getProcessInstanceId()).singleResult(); |
| | | BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus()); |
| | | runtimeService.updateBusinessStatus(processInvalidBo.getProcessInstanceId(), BusinessStatusEnum.INVALID.getStatus()); |
| | | runtimeService.deleteProcessInstance(processInvalidBo.getProcessInstanceId(), deleteReason); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è¿è¡ä¸çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunAndHisInstance(List<String> processInstanceIds) { |
| | | try { |
| | | // 1.å é¤è¿è¡ä¸æµç¨å®ä¾ |
| | | List<Task> list = QueryUtils.taskQuery(processInstanceIds).list(); |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | | } |
| | | runtimeService.bulkDeleteProcessInstances(processInstanceIds, LoginHelper.getUserId() + "å é¤äºå½åæµç¨ç³è¯·"); |
| | | // 2.å é¤åå²è®°å½ |
| | | List<HistoricProcessInstance> historicProcessInstanceList = QueryUtils.hisInstanceQuery(new HashSet<>(processInstanceIds)).list(); |
| | | if (ObjectUtil.isNotEmpty(historicProcessInstanceList)) { |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | } |
| | | wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä¸å¡idå é¤ è¿è¡ä¸çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param businessKeys ä¸å¡id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunAndHisInstanceByBusinessKeys(List<String> businessKeys) { |
| | | try { |
| | | // 1.å é¤è¿è¡ä¸æµç¨å®ä¾ |
| | | List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys); |
| | | if (CollUtil.isEmpty(actHiProcinsts)) { |
| | | log.warn("å½åä¸å¡ID:{}æ¥è¯¢å°æµç¨å®ä¾ä¸ºç©ºï¼", businessKeys); |
| | | return false; |
| | | } |
| | | List<String> processInstanceIds = StreamUtils.toList(actHiProcinsts, ActHiProcinst::getId); |
| | | List<Task> list = QueryUtils.taskQuery(processInstanceIds).list(); |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | | } |
| | | runtimeService.bulkDeleteProcessInstances(processInstanceIds, LoginHelper.getUserId() + "å é¤äºå½åæµç¨ç³è¯·"); |
| | | // 2.å é¤åå²è®°å½ |
| | | List<HistoricProcessInstance> historicProcessInstanceList = QueryUtils.hisInstanceQuery(new HashSet<>(processInstanceIds)).list(); |
| | | if (ObjectUtil.isNotEmpty(historicProcessInstanceList)) { |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | } |
| | | wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 已宿çå®ä¾ å é¤ç¨å®ä¾ï¼å é¤åå²è®°å½ï¼å é¤ä¸å¡ä¸æµç¨å
³èä¿¡æ¯ |
| | | * |
| | | * @param processInstanceIds æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteFinishAndHisInstance(List<String> processInstanceIds) { |
| | | try { |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¤éæµç¨ç³è¯· |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean cancelProcessApply(String processInstanceId) { |
| | | try { |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId) |
| | | .startedBy(String.valueOf(LoginHelper.getUserId())).singleResult(); |
| | | if (ObjectUtil.isNull(processInstance)) { |
| | | throw new ServiceException("æ¨ä¸æ¯æµç¨å起人,æ¤é失败!"); |
| | | } |
| | | if (processInstance.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | BusinessStatusEnum.checkCancelStatus(processInstance.getBusinessStatus()); |
| | | List<Task> taskList = QueryUtils.taskQuery(processInstanceId).list(); |
| | | for (Task task : taskList) { |
| | | taskService.setAssignee(task.getId(), null); |
| | | taskService.addComment(task.getId(), processInstanceId, TaskStatusEnum.CANCEL.getStatus(), LoginHelper.getLoginUser().getNickname() + "ï¼æ¤éç³è¯·"); |
| | | } |
| | | HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery().finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0); |
| | | List<String> nodeIds = StreamUtils.toList(taskList, Task::getTaskDefinitionKey); |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .processInstanceId(processInstanceId) |
| | | .moveActivityIdsToSingleActivityId(nodeIds, historicTaskInstance.getTaskDefinitionKey()).changeState(); |
| | | Task task = QueryUtils.taskQuery(processInstanceId).list().get(0); |
| | | taskService.setAssignee(task.getId(), historicTaskInstance.getAssignee()); |
| | | //è·åå¹¶è¡ç½å
³æ§è¡åä¿ççæ§è¡å®ä¾æ°æ® |
| | | ExecutionChildByExecutionIdCmd childByExecutionIdCmd = new ExecutionChildByExecutionIdCmd(task.getExecutionId()); |
| | | List<ExecutionEntity> executionEntities = managementService.executeCommand(childByExecutionIdCmd); |
| | | //å 餿µç¨å®ä¾å徿°æ® |
| | | for (ExecutionEntity executionEntity : executionEntities) { |
| | | DeleteExecutionCmd deleteExecutionCmd = new DeleteExecutionCmd(executionEntity.getId()); |
| | | managementService.executeCommand(deleteExecutionCmd); |
| | | } |
| | | runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.CANCEL.getStatus()); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException("æ¤é失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å½åç»å½äººåæ® |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo bo, PageQuery pageQuery) { |
| | | List<ProcessInstanceVo> list = new ArrayList<>(); |
| | | HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery(); |
| | | query.startedBy(String.valueOf(LoginHelper.getUserId())); |
| | | if (StringUtils.isNotBlank(bo.getName())) { |
| | | query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getKey())) { |
| | | query.processDefinitionKey(bo.getKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getBusinessKey())) { |
| | | query.processInstanceBusinessKey(bo.getBusinessKey()); |
| | | } |
| | | if (StringUtils.isNotBlank(bo.getCategoryCode())) { |
| | | query.processDefinitionCategory(bo.getCategoryCode()); |
| | | } |
| | | query.orderByProcessInstanceStartTime().desc(); |
| | | List<HistoricProcessInstance> historicProcessInstanceList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | List<TaskVo> taskVoList = new ArrayList<>(); |
| | | if (CollUtil.isNotEmpty(historicProcessInstanceList)) { |
| | | List<String> processInstanceIds = StreamUtils.toList(historicProcessInstanceList, HistoricProcessInstance::getId); |
| | | List<Task> taskList = QueryUtils.taskQuery(processInstanceIds).list(); |
| | | for (Task task : taskList) { |
| | | taskVoList.add(BeanUtil.toBean(task, TaskVo.class)); |
| | | } |
| | | } |
| | | for (HistoricProcessInstance processInstance : historicProcessInstanceList) { |
| | | ProcessInstanceVo processInstanceVo = BeanUtil.toBean(processInstance, ProcessInstanceVo.class); |
| | | processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstance.getBusinessStatus())); |
| | | if (CollUtil.isNotEmpty(taskVoList)) { |
| | | List<TaskVo> collect = StreamUtils.filter(taskVoList, e -> e.getProcessInstanceId().equals(processInstance.getId())); |
| | | processInstanceVo.setTaskVoList(CollUtil.isNotEmpty(collect) ? collect : Collections.emptyList()); |
| | | } |
| | | list.add(processInstanceVo); |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | long count = query.count(); |
| | | TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build(); |
| | | build.setRows(list); |
| | | build.setTotal(count); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * ä»»å¡å¬å(ç»å½åä»»å¡åç人åéç«å
ä¿¡ï¼é®ä»¶ï¼çä¿¡ç) |
| | | * |
| | | * @param taskUrgingBo ä»»å¡å¬å |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean taskUrging(TaskUrgingBo taskUrgingBo) { |
| | | try { |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(taskUrgingBo.getProcessInstanceId()).singleResult(); |
| | | if (processInstance == null) { |
| | | throw new ServiceException("ä»»å¡å·²ç»æï¼"); |
| | | } |
| | | String message = taskUrgingBo.getMessage(); |
| | | if (StringUtils.isBlank(message)) { |
| | | message = "æ¨çã" + processInstance.getName() + "ãåæ®è¿æªå®¡æ¹ï¼è¯·æ¨åæ¶å¤çã"; |
| | | } |
| | | List<Task> list = QueryUtils.taskQuery(taskUrgingBo.getProcessInstanceId()).list(); |
| | | WorkflowUtils.sendMessage(list, processInstance.getName(), taskUrgingBo.getMessageType(), message); |
| | | } catch (ServiceException e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | return true; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.domain.dto.RoleDTO; |
| | | import org.dromara.common.core.domain.dto.UserDTO; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.service.UserService; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.workflow.common.constant.FlowConstant; |
| | | import org.dromara.workflow.common.enums.BusinessStatusEnum; |
| | | import org.dromara.workflow.common.enums.TaskStatusEnum; |
| | | import org.dromara.workflow.domain.ActHiTaskinst; |
| | | import org.dromara.workflow.domain.WfTaskBackNode; |
| | | import org.dromara.workflow.domain.bo.*; |
| | | import org.dromara.workflow.domain.vo.*; |
| | | import org.dromara.workflow.flowable.cmd.*; |
| | | import org.dromara.workflow.flowable.strategy.FlowEventStrategy; |
| | | import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler; |
| | | import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler; |
| | | import org.dromara.workflow.mapper.ActHiTaskinstMapper; |
| | | import org.dromara.workflow.mapper.ActTaskMapper; |
| | | import org.dromara.workflow.service.IActTaskService; |
| | | import org.dromara.workflow.service.IWfDefinitionConfigService; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | | import org.dromara.workflow.service.IWfTaskBackNodeService; |
| | | import org.dromara.workflow.utils.ModelUtils; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.dromara.workflow.utils.WorkflowUtils; |
| | | import org.flowable.common.engine.api.FlowableObjectNotFoundException; |
| | | import org.flowable.common.engine.impl.identity.Authentication; |
| | | import org.flowable.engine.*; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstanceQuery; |
| | | import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; |
| | | import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; |
| | | import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
| | | import org.flowable.engine.runtime.ProcessInstance; |
| | | 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.service.impl.persistence.entity.TaskEntity; |
| | | import org.flowable.variable.api.persistence.entity.VariableInstance; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static org.dromara.workflow.common.constant.FlowConstant.*; |
| | | |
| | | /** |
| | | * ä»»å¡ æå¡å±å®ç° |
| | | * |
| | | * @author may |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class ActTaskServiceImpl implements IActTaskService { |
| | | |
| | | private final RuntimeService runtimeService; |
| | | private final TaskService taskService; |
| | | private final HistoryService historyService; |
| | | private final IdentityService identityService; |
| | | private final ManagementService managementService; |
| | | private final FlowEventStrategy flowEventStrategy; |
| | | private final ActTaskMapper actTaskMapper; |
| | | private final IWfTaskBackNodeService wfTaskBackNodeService; |
| | | private final ActHiTaskinstMapper actHiTaskinstMapper; |
| | | private final IWfNodeConfigService wfNodeConfigService; |
| | | private final IWfDefinitionConfigService wfDefinitionConfigService; |
| | | private final UserService userService; |
| | | |
| | | /** |
| | | * å¯å¨ä»»å¡ |
| | | * |
| | | * @param startProcessBo å¯å¨æµç¨åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Map<String, Object> startWorkFlow(StartProcessBo startProcessBo) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if (StringUtils.isBlank(startProcessBo.getBusinessKey())) { |
| | | throw new ServiceException("å¯å¨å·¥ä½æµæ¶å¿
é¡»å
å«ä¸å¡ID"); |
| | | } |
| | | // 夿å½åä¸å¡æ¯å¦å¯å¨è¿æµç¨ |
| | | HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery(); |
| | | HistoricProcessInstance historicProcessInstance = query.processInstanceBusinessKey(startProcessBo.getBusinessKey()).singleResult(); |
| | | if (ObjectUtil.isNotEmpty(historicProcessInstance)) { |
| | | BusinessStatusEnum.checkStartStatus(historicProcessInstance.getBusinessStatus()); |
| | | } |
| | | List<Task> taskResult = QueryUtils.taskQuery().processInstanceBusinessKey(startProcessBo.getBusinessKey()).list(); |
| | | if (CollUtil.isNotEmpty(taskResult)) { |
| | | if (CollUtil.isNotEmpty(startProcessBo.getVariables())) { |
| | | taskService.setVariables(taskResult.get(0).getId(), startProcessBo.getVariables()); |
| | | } |
| | | map.put(PROCESS_INSTANCE_ID, taskResult.get(0).getProcessInstanceId()); |
| | | map.put("taskId", taskResult.get(0).getId()); |
| | | return map; |
| | | } |
| | | WfDefinitionConfigVo wfDefinitionConfigVo = wfDefinitionConfigService.getByTableNameLastVersion(startProcessBo.getTableName()); |
| | | if (wfDefinitionConfigVo == null) { |
| | | throw new ServiceException("è¯·å°æµç¨å®ä¹ç»å®ä¸å¡è¡¨å䏿µç¨KEYï¼"); |
| | | } |
| | | // 设置å¯å¨äºº |
| | | identityService.setAuthenticatedUserId(String.valueOf(LoginHelper.getUserId())); |
| | | Authentication.setAuthenticatedUserId(String.valueOf(LoginHelper.getUserId())); |
| | | // å¯å¨æµç¨å®ä¾ï¼æäº¤ç³è¯·ï¼ |
| | | Map<String, Object> variables = startProcessBo.getVariables(); |
| | | // å¯å¨è·³è¿è¡¨è¾¾å¼ |
| | | variables.put(FLOWABLE_SKIP_EXPRESSION_ENABLED, true); |
| | | // æµç¨å起人 |
| | | variables.put(INITIATOR, (String.valueOf(LoginHelper.getUserId()))); |
| | | ProcessInstance pi; |
| | | try { |
| | | if (TenantHelper.isEnable()) { |
| | | pi = runtimeService.startProcessInstanceByKeyAndTenantId(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables, TenantHelper.getTenantId()); |
| | | } else { |
| | | pi = runtimeService.startProcessInstanceByKey(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables); |
| | | } |
| | | } catch (FlowableObjectNotFoundException e) { |
| | | throw new ServiceException("æ¾ä¸å°å½åã" + wfDefinitionConfigVo.getProcessKey() + "ãæµç¨å®ä¹ï¼"); |
| | | } |
| | | // å°æµç¨å®ä¹åç§° ä½ä¸º æµç¨å®ä¾åç§° |
| | | runtimeService.setProcessInstanceName(pi.getProcessInstanceId(), pi.getProcessDefinitionName()); |
| | | // ç³è¯·äººæ§è¡æµç¨ |
| | | List<Task> taskList = QueryUtils.taskQuery(pi.getId()).list(); |
| | | if (taskList.size() > 1) { |
| | | throw new ServiceException("è¯·æ£æ¥æµç¨ç¬¬ä¸ä¸ªç¯èæ¯å¦ä¸ºç³è¯·äººï¼"); |
| | | } |
| | | |
| | | runtimeService.updateBusinessStatus(pi.getProcessInstanceId(), BusinessStatusEnum.DRAFT.getStatus()); |
| | | taskService.setAssignee(taskList.get(0).getId(), LoginHelper.getUserId().toString()); |
| | | taskService.setVariable(taskList.get(0).getId(), PROCESS_INSTANCE_ID, pi.getProcessInstanceId()); |
| | | taskService.setVariable(taskList.get(0).getId(), BUSINESS_KEY, pi.getBusinessKey()); |
| | | map.put("processInstanceId", pi.getProcessInstanceId()); |
| | | map.put("taskId", taskList.get(0).getId()); |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * åçä»»å¡ |
| | | * |
| | | * @param completeTaskBo åçä»»å¡åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean completeTask(CompleteTaskBo completeTaskBo) { |
| | | try { |
| | | List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles(); |
| | | String userId = String.valueOf(LoginHelper.getUserId()); |
| | | TaskQuery taskQuery = QueryUtils.taskQuery(); |
| | | taskQuery.taskId(completeTaskBo.getTaskId()).taskCandidateOrAssigned(userId); |
| | | if (CollUtil.isNotEmpty(roles)) { |
| | | List<String> groupIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId())); |
| | | taskQuery.taskCandidateGroupIn(groupIds); |
| | | } |
| | | Task task = taskQuery.singleResult(); |
| | | if (task == null) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult(); |
| | | //åçå§æä»»å¡ |
| | | if (ObjectUtil.isNotEmpty(task.getDelegationState()) && FlowConstant.PENDING.equals(task.getDelegationState().name())) { |
| | | taskService.resolveTask(completeTaskBo.getTaskId()); |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isNotBlank(completeTaskBo.getMessage()) ? completeTaskBo.getMessage() : StrUtil.EMPTY); |
| | | taskService.complete(newTask.getId()); |
| | | return true; |
| | | } |
| | | //éä»¶ä¸ä¼ |
| | | AttachmentCmd attachmentCmd = new AttachmentCmd(completeTaskBo.getFileId(), task.getId(), task.getProcessInstanceId()); |
| | | managementService.executeCommand(attachmentCmd); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey()); |
| | | String businessStatus = WorkflowUtils.getBusinessStatus(task.getProcessInstanceId()); |
| | | if (BusinessStatusEnum.DRAFT.getStatus().equals(businessStatus) || BusinessStatusEnum.BACK.getStatus().equals(businessStatus) || BusinessStatusEnum.CANCEL.getStatus().equals(businessStatus)) { |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(processInstance.getBusinessKey(), businessStatus, true); |
| | | } |
| | | } |
| | | runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.WAITING.getStatus()); |
| | | String key = processInstance.getProcessDefinitionKey() + "_" + task.getTaskDefinitionKey(); |
| | | FlowTaskEventHandler taskHandler = flowEventStrategy.getTaskHandler(key); |
| | | if (taskHandler != null) { |
| | | taskHandler.handleTask(task.getId(), processInstance.getBusinessKey()); |
| | | } |
| | | //åçæè§ |
| | | taskService.addComment(completeTaskBo.getTaskId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isBlank(completeTaskBo.getMessage()) ? "åæ" : completeTaskBo.getMessage()); |
| | | //åçä»»å¡ |
| | | taskService.setAssignee(task.getId(), userId); |
| | | if (CollUtil.isNotEmpty(completeTaskBo.getVariables())) { |
| | | taskService.complete(completeTaskBo.getTaskId(), completeTaskBo.getVariables()); |
| | | } else { |
| | | taskService.complete(completeTaskBo.getTaskId()); |
| | | } |
| | | //è®°å½æ§è¡è¿çæµç¨ä»»å¡èç¹ |
| | | wfTaskBackNodeService.recordExecuteNode(task); |
| | | ProcessInstance pi = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult(); |
| | | if (pi == null) { |
| | | UpdateBusinessStatusCmd updateBusinessStatusCmd = new UpdateBusinessStatusCmd(task.getProcessInstanceId(), BusinessStatusEnum.FINISH.getStatus()); |
| | | managementService.executeCommand(updateBusinessStatusCmd); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.FINISH.getStatus(), false); |
| | | } |
| | | } else { |
| | | List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list(); |
| | | for (Task t : list) { |
| | | if (ModelUtils.isUserTask(t.getProcessDefinitionId(), t.getTaskDefinitionKey())) { |
| | | List<HistoricIdentityLink> links = historyService.getHistoricIdentityLinksForTask(t.getId()); |
| | | if (CollUtil.isEmpty(links) && StringUtils.isBlank(t.getAssignee())) { |
| | | throw new ServiceException("ä¸ä¸èç¹ã" + t.getName() + "ãæ²¡æåç人!"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (CollUtil.isNotEmpty(list) && CollUtil.isNotEmpty(completeTaskBo.getWfCopyList())) { |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.COPY.getStatus(), LoginHelper.getLoginUser().getNickname() + "ãæéãç»" + String.join(",", StreamUtils.toList(completeTaskBo.getWfCopyList(), WfCopy::getUserName))); |
| | | taskService.complete(newTask.getId()); |
| | | List<Task> taskList = QueryUtils.taskQuery(task.getProcessInstanceId()).list(); |
| | | WorkflowUtils.createCopyTask(taskList, StreamUtils.toList(completeTaskBo.getWfCopyList(), WfCopy::getUserId)); |
| | | } |
| | | sendMessage(list, processInstance.getName(), completeTaskBo.getMessageType(), null); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * åéæ¶æ¯ |
| | | * |
| | | * @param list ä»»å¡ |
| | | * @param name æµç¨åç§° |
| | | * @param messageType æ¶æ¯ç±»å |
| | | * @param message æ¶æ¯å
容ï¼ä¸ºç©ºååéé»è®¤é
ç½®çæ¶æ¯å
容 |
| | | */ |
| | | @Async |
| | | public void sendMessage(List<Task> list, String name, List<String> messageType, String message) { |
| | | WorkflowUtils.sendMessage(list, name, messageType, message); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery) { |
| | | QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>(); |
| | | List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles(); |
| | | List<String> roleIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId())); |
| | | String userId = String.valueOf(LoginHelper.getUserId()); |
| | | queryWrapper.eq("t.business_status_", BusinessStatusEnum.WAITING.getStatus()); |
| | | queryWrapper.eq(TenantHelper.isEnable(), "t.tenant_id_", TenantHelper.getTenantId()); |
| | | queryWrapper.and(w1 -> w1.eq("t.assignee_", userId).or(w2 -> w2.isNull("t.assignee_").apply("exists ( select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = t.ID_ and LINK.TYPE_ = 'candidate' " + "and (LINK.USER_ID_ = {0} or ( LINK.GROUP_ID_ IN " + getInParam(roleIds) + " ) ))", userId))); |
| | | if (StringUtils.isNotBlank(taskBo.getName())) { |
| | | queryWrapper.like("t.name_", taskBo.getName()); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) { |
| | | queryWrapper.like("t.processDefinitionName", taskBo.getProcessDefinitionName()); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) { |
| | | queryWrapper.eq("t.processDefinitionKey", taskBo.getProcessDefinitionKey()); |
| | | } |
| | | Page<TaskVo> page = actTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper); |
| | | |
| | | List<TaskVo> taskList = page.getRecords(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (TaskVo task : taskList) { |
| | | task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus())); |
| | | task.setParticipantVo(WorkflowUtils.getCurrentTaskParticipant(task.getId())); |
| | | task.setMultiInstance(WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()) != null); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | private String getInParam(List<String> param) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("("); |
| | | for (int i = 0; i < param.size(); i++) { |
| | | sb.append("'").append(param.get(i)).append("'"); |
| | | if (i != param.size() - 1) { |
| | | sb.append(","); |
| | | } |
| | | } |
| | | sb.append(")"); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå¾
åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery) { |
| | | TaskQuery query = QueryUtils.taskQuery(); |
| | | if (StringUtils.isNotBlank(taskBo.getName())) { |
| | | query.taskNameLike("%" + taskBo.getName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) { |
| | | query.processDefinitionNameLike("%" + taskBo.getProcessDefinitionName() + "%"); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) { |
| | | query.processDefinitionKey(taskBo.getProcessDefinitionKey()); |
| | | } |
| | | query.orderByTaskCreateTime().desc(); |
| | | List<Task> taskList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize()); |
| | | List<ProcessInstance> processInstanceList = null; |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | Set<String> processInstanceIds = StreamUtils.toSet(taskList, Task::getProcessInstanceId); |
| | | processInstanceList = QueryUtils.instanceQuery(processInstanceIds).list(); |
| | | } |
| | | List<TaskVo> list = new ArrayList<>(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(taskList, Task::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (Task task : taskList) { |
| | | TaskVo taskVo = BeanUtil.toBean(task, TaskVo.class); |
| | | if (CollUtil.isNotEmpty(processInstanceList)) { |
| | | processInstanceList.stream().filter(e -> e.getId().equals(task.getProcessInstanceId())).findFirst().ifPresent(e -> { |
| | | taskVo.setBusinessStatus(e.getBusinessStatus()); |
| | | taskVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(taskVo.getBusinessStatus())); |
| | | taskVo.setProcessDefinitionKey(e.getProcessDefinitionKey()); |
| | | taskVo.setProcessDefinitionName(e.getProcessDefinitionName()); |
| | | taskVo.setProcessDefinitionVersion(e.getProcessDefinitionVersion()); |
| | | taskVo.setBusinessKey(e.getBusinessKey()); |
| | | }); |
| | | } |
| | | taskVo.setAssignee(StringUtils.isNotBlank(task.getAssignee()) ? Long.valueOf(task.getAssignee()) : null); |
| | | taskVo.setParticipantVo(WorkflowUtils.getCurrentTaskParticipant(task.getId())); |
| | | taskVo.setMultiInstance(WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()) != null); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(taskVo::setWfNodeConfigVo); |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(taskVo::setWfNodeConfigVo); |
| | | } |
| | | list.add(taskVo); |
| | | } |
| | | } |
| | | long count = query.count(); |
| | | TableDataInfo<TaskVo> build = TableDataInfo.build(); |
| | | build.setRows(list); |
| | | build.setTotal(count); |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery) { |
| | | String userId = String.valueOf(LoginHelper.getUserId()); |
| | | QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.like(StringUtils.isNotBlank(taskBo.getName()), "t.name_", taskBo.getName()); |
| | | queryWrapper.like(StringUtils.isNotBlank(taskBo.getProcessDefinitionName()), "t.processDefinitionName", taskBo.getProcessDefinitionName()); |
| | | queryWrapper.eq(StringUtils.isNotBlank(taskBo.getProcessDefinitionKey()), "t.processDefinitionKey", taskBo.getProcessDefinitionKey()); |
| | | queryWrapper.eq("t.assignee_", userId); |
| | | Page<TaskVo> page = actTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper); |
| | | |
| | | List<TaskVo> taskList = page.getRecords(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (TaskVo task : taskList) { |
| | | task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus())); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çæé |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery) { |
| | | QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>(); |
| | | String userId = String.valueOf(LoginHelper.getUserId()); |
| | | if (StringUtils.isNotBlank(taskBo.getName())) { |
| | | queryWrapper.like("t.name_", taskBo.getName()); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) { |
| | | queryWrapper.like("t.processDefinitionName", taskBo.getProcessDefinitionName()); |
| | | } |
| | | if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) { |
| | | queryWrapper.eq("t.processDefinitionKey", taskBo.getProcessDefinitionKey()); |
| | | } |
| | | queryWrapper.eq("t.assignee_", userId); |
| | | Page<TaskVo> page = actTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper); |
| | | |
| | | List<TaskVo> taskList = page.getRecords(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (TaskVo task : taskList) { |
| | | task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus())); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç§æ·ææå·²åä»»å¡ |
| | | * |
| | | * @param taskBo åæ° |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery) { |
| | | QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.like(StringUtils.isNotBlank(taskBo.getName()), "t.name_", taskBo.getName()); |
| | | queryWrapper.like(StringUtils.isNotBlank(taskBo.getProcessDefinitionName()), "t.processDefinitionName", taskBo.getProcessDefinitionName()); |
| | | queryWrapper.eq(StringUtils.isNotBlank(taskBo.getProcessDefinitionKey()), "t.processDefinitionKey", taskBo.getProcessDefinitionKey()); |
| | | Page<TaskVo> page = actTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper); |
| | | |
| | | List<TaskVo> taskList = page.getRecords(); |
| | | if (CollUtil.isNotEmpty(taskList)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (TaskVo task : taskList) { |
| | | task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus())); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo); |
| | | } |
| | | } |
| | | } |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * å§æ´¾ä»»å¡ |
| | | * |
| | | * @param delegateBo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean delegateTask(DelegateBo delegateBo) { |
| | | TaskQuery query = QueryUtils.taskQuery(); |
| | | TaskEntity task = (TaskEntity) query.taskId(delegateBo.getTaskId()).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())).singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | try { |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.PENDING.getStatus(), "ã" + LoginHelper.getLoginUser().getNickname() + "ãå§æ´¾ç»ã" + delegateBo.getNickName() + "ã"); |
| | | //å§æä»»å¡ |
| | | taskService.delegateTask(delegateBo.getTaskId(), delegateBo.getUserId()); |
| | | //åççæçä»»å¡è®°å½ |
| | | taskService.complete(newTask.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç»æ¢ä»»å¡ |
| | | * |
| | | * @param terminationBo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean terminationTask(TerminationBo terminationBo) { |
| | | TaskQuery query = QueryUtils.taskQuery(); |
| | | Task task = query.taskId(terminationBo.getTaskId()).singleResult(); |
| | | |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); |
| | | BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus()); |
| | | try { |
| | | if (StringUtils.isBlank(terminationBo.getComment())) { |
| | | terminationBo.setComment(LoginHelper.getLoginUser().getNickname() + "ç»æ¢äºç³è¯·"); |
| | | } else { |
| | | terminationBo.setComment(LoginHelper.getLoginUser().getNickname() + "ç»æ¢äºç³è¯·ï¼" + terminationBo.getComment()); |
| | | } |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.TERMINATION.getStatus(), terminationBo.getComment()); |
| | | List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list(); |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | | } |
| | | runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.TERMINATION.getStatus()); |
| | | runtimeService.deleteProcessInstance(task.getProcessInstanceId(), StrUtil.EMPTY); |
| | | } |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * |
| | | * @param transmitBo åæ° |
| | | */ |
| | | @Override |
| | | public boolean transferTask(TransmitBo transmitBo) { |
| | | Task task = QueryUtils.taskQuery().taskId(transmitBo.getTaskId()).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())).singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | try { |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.TRANSFER.getStatus(), StringUtils.isNotBlank(transmitBo.getComment()) ? transmitBo.getComment() : LoginHelper.getUsername() + "转åäºä»»å¡"); |
| | | taskService.complete(newTask.getId()); |
| | | taskService.setAssignee(task.getId(), transmitBo.getUserId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡å ç¾ |
| | | * |
| | | * @param addMultiBo åæ° |
| | | */ |
| | | @Override |
| | | public boolean addMultiInstanceExecution(AddMultiBo addMultiBo) { |
| | | TaskQuery taskQuery = QueryUtils.taskQuery(); |
| | | taskQuery.taskId(addMultiBo.getTaskId()); |
| | | if (!LoginHelper.isSuperAdmin() && !LoginHelper.isTenantAdmin()) { |
| | | taskQuery.taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())); |
| | | } |
| | | Task task = taskQuery.singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | String taskDefinitionKey = task.getTaskDefinitionKey(); |
| | | String processInstanceId = task.getProcessInstanceId(); |
| | | String processDefinitionId = task.getProcessDefinitionId(); |
| | | |
| | | try { |
| | | MultiInstanceVo multiInstanceVo = WorkflowUtils.isMultiInstance(processDefinitionId, taskDefinitionKey); |
| | | if (multiInstanceVo == null) { |
| | | throw new ServiceException("å½åç¯è䏿¯ä¼ç¾èç¹"); |
| | | } |
| | | if (multiInstanceVo.getType() instanceof ParallelMultiInstanceBehavior) { |
| | | for (Long assignee : addMultiBo.getAssignees()) { |
| | | runtimeService.addMultiInstanceExecution(taskDefinitionKey, processInstanceId, Collections.singletonMap(multiInstanceVo.getAssignee(), assignee)); |
| | | } |
| | | } else if (multiInstanceVo.getType() instanceof SequentialMultiInstanceBehavior) { |
| | | AddSequenceMultiInstanceCmd addSequenceMultiInstanceCmd = new AddSequenceMultiInstanceCmd(task.getExecutionId(), multiInstanceVo.getAssigneeList(), addMultiBo.getAssignees()); |
| | | managementService.executeCommand(addSequenceMultiInstanceCmd); |
| | | } |
| | | List<String> assigneeNames = addMultiBo.getAssigneeNames(); |
| | | String username = LoginHelper.getUsername(); |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), processInstanceId, TaskStatusEnum.SIGN.getStatus(), username + "å ç¾ã" + String.join(StringUtils.SEPARATOR, assigneeNames) + "ã"); |
| | | taskService.complete(newTask.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¼ç¾ä»»å¡åç¾ |
| | | * |
| | | * @param deleteMultiBo åæ° |
| | | */ |
| | | @Override |
| | | public boolean deleteMultiInstanceExecution(DeleteMultiBo deleteMultiBo) { |
| | | TaskQuery taskQuery = QueryUtils.taskQuery(); |
| | | taskQuery.taskId(deleteMultiBo.getTaskId()); |
| | | if (!LoginHelper.isSuperAdmin() && !LoginHelper.isTenantAdmin()) { |
| | | taskQuery.taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())); |
| | | } |
| | | Task task = taskQuery.singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | String taskDefinitionKey = task.getTaskDefinitionKey(); |
| | | String processInstanceId = task.getProcessInstanceId(); |
| | | String processDefinitionId = task.getProcessDefinitionId(); |
| | | try { |
| | | MultiInstanceVo multiInstanceVo = WorkflowUtils.isMultiInstance(processDefinitionId, taskDefinitionKey); |
| | | if (multiInstanceVo == null) { |
| | | throw new ServiceException("å½åç¯è䏿¯ä¼ç¾èç¹"); |
| | | } |
| | | if (multiInstanceVo.getType() instanceof ParallelMultiInstanceBehavior) { |
| | | for (String executionId : deleteMultiBo.getExecutionIds()) { |
| | | runtimeService.deleteMultiInstanceExecution(executionId, false); |
| | | } |
| | | for (String taskId : deleteMultiBo.getTaskIds()) { |
| | | historyService.deleteHistoricTaskInstance(taskId); |
| | | } |
| | | } else if (multiInstanceVo.getType() instanceof SequentialMultiInstanceBehavior) { |
| | | DeleteSequenceMultiInstanceCmd deleteSequenceMultiInstanceCmd = new DeleteSequenceMultiInstanceCmd(task.getAssignee(), task.getExecutionId(), multiInstanceVo.getAssigneeList(), deleteMultiBo.getAssigneeIds()); |
| | | managementService.executeCommand(deleteSequenceMultiInstanceCmd); |
| | | } |
| | | List<String> assigneeNames = deleteMultiBo.getAssigneeNames(); |
| | | String username = LoginHelper.getUsername(); |
| | | TaskEntity newTask = WorkflowUtils.createNewTask(task); |
| | | taskService.addComment(newTask.getId(), processInstanceId, TaskStatusEnum.SIGN_OFF.getStatus(), username + "åç¾ã" + String.join(StringUtils.SEPARATOR, assigneeNames) + "ã"); |
| | | taskService.complete(newTask.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 驳åå®¡æ¹ |
| | | * |
| | | * @param backProcessBo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public String backProcess(BackProcessBo backProcessBo) { |
| | | TaskQuery query = QueryUtils.taskQuery(); |
| | | String userId = String.valueOf(LoginHelper.getUserId()); |
| | | Task task = query.taskId(backProcessBo.getTaskId()).taskCandidateOrAssigned(userId).singleResult(); |
| | | if (ObjectUtil.isEmpty(task)) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); |
| | | } |
| | | if (task.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | try { |
| | | String processInstanceId = task.getProcessInstanceId(); |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult(); |
| | | //è·åå¹¶è¡ç½å
³æ§è¡åä¿ççæ§è¡å®ä¾æ°æ® |
| | | ExecutionChildByExecutionIdCmd childByExecutionIdCmd = new ExecutionChildByExecutionIdCmd(task.getExecutionId()); |
| | | List<ExecutionEntity> executionEntities = managementService.executeCommand(childByExecutionIdCmd); |
| | | //æ ¡éªåæ® |
| | | BusinessStatusEnum.checkBackStatus(processInstance.getBusinessStatus()); |
| | | //夿æ¯å¦æå¤ä¸ªä»»å¡ |
| | | List<Task> taskList = QueryUtils.taskQuery(processInstanceId).list(); |
| | | String backTaskDefinitionKey = backProcessBo.getTargetActivityId(); |
| | | taskService.addComment(task.getId(), processInstanceId, TaskStatusEnum.BACK.getStatus(), StringUtils.isNotBlank(backProcessBo.getMessage()) ? backProcessBo.getMessage() : "éå"); |
| | | if (taskList.size() > 1) { |
| | | //å½åå¤ä¸ªä»»å¡é©³åå°å个èç¹ |
| | | runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveActivityIdsToSingleActivityId(taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()), backTaskDefinitionKey).changeState(); |
| | | ActHiTaskinst actHiTaskinst = new ActHiTaskinst(); |
| | | actHiTaskinst.setAssignee(userId); |
| | | actHiTaskinst.setId(task.getId()); |
| | | actHiTaskinstMapper.updateById(actHiTaskinst); |
| | | } else { |
| | | //å½åå个èç¹é©³åå个èç¹ |
| | | runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveActivityIdTo(task.getTaskDefinitionKey(), backTaskDefinitionKey).changeState(); |
| | | } |
| | | //å é¤å¹¶è¡ç¯èæªåçè®°å½ |
| | | MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); |
| | | if (multiInstance == null && taskList.size() > 1) { |
| | | List<Task> tasks = StreamUtils.filter(taskList, e -> !e.getTaskDefinitionKey().equals(task.getTaskDefinitionKey())); |
| | | actHiTaskinstMapper.deleteBatchIds(StreamUtils.toList(tasks, Task::getId)); |
| | | } |
| | | |
| | | |
| | | List<HistoricTaskInstance> instanceList = QueryUtils.hisTaskInstanceQuery(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().desc().list(); |
| | | List<Task> list = QueryUtils.taskQuery(processInstanceId).list(); |
| | | for (Task t : list) { |
| | | instanceList.stream().filter(e -> e.getTaskDefinitionKey().equals(t.getTaskDefinitionKey())).findFirst().ifPresent(e -> { |
| | | taskService.setAssignee(t.getId(), e.getAssignee()); |
| | | }); |
| | | } |
| | | //åéæ¶æ¯ |
| | | String message = "æ¨çã" + processInstance.getName() + "ã忮已ç»è¢«é©³åï¼è¯·æ¨æ³¨ææ¥æ¶ã"; |
| | | sendMessage(list, processInstance.getName(), backProcessBo.getMessageType(), message); |
| | | //å 餿µç¨å®ä¾å徿°æ® |
| | | for (ExecutionEntity executionEntity : executionEntities) { |
| | | DeleteExecutionCmd deleteExecutionCmd = new DeleteExecutionCmd(executionEntity.getId()); |
| | | managementService.executeCommand(deleteExecutionCmd); |
| | | } |
| | | |
| | | WfTaskBackNode wfTaskBackNode = wfTaskBackNodeService.getListByInstanceIdAndNodeId(task.getProcessInstanceId(), backProcessBo.getTargetActivityId()); |
| | | if (ObjectUtil.isNotNull(wfTaskBackNode) && wfTaskBackNode.getOrderNo() == 0) { |
| | | runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.BACK.getStatus()); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false); |
| | | } |
| | | } |
| | | //å é¤é©³ååçæµç¨èç¹ |
| | | wfTaskBackNodeService.deleteBackTaskNode(processInstanceId, backProcessBo.getTargetActivityId()); |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | return task.getProcessInstanceId(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»»å¡åç人 |
| | | * |
| | | * @param taskIds ä»»å¡id |
| | | * @param userId åç人id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean updateAssignee(String[] taskIds, String userId) { |
| | | try { |
| | | List<Task> list = QueryUtils.taskQuery().taskIds(Arrays.asList(taskIds)).list(); |
| | | for (Task task : list) { |
| | | taskService.setAssignee(task.getId(), userId); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åé |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @Override |
| | | public List<VariableVo> getInstanceVariable(String taskId) { |
| | | List<VariableVo> variableVoList = new ArrayList<>(); |
| | | Map<String, VariableInstance> variableInstances = taskService.getVariableInstances(taskId); |
| | | if (CollUtil.isNotEmpty(variableInstances)) { |
| | | for (Map.Entry<String, VariableInstance> entry : variableInstances.entrySet()) { |
| | | VariableVo variableVo = new VariableVo(); |
| | | variableVo.setKey(entry.getKey()); |
| | | variableVo.setValue(entry.getValue().getValue().toString()); |
| | | variableVoList.add(variableVo); |
| | | } |
| | | } |
| | | return variableVoList; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµä»»å¡ç¨æ·éæ©å ç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | * @return |
| | | */ |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public String getTaskUserIdsByAddMultiInstance(String taskId) { |
| | | Task task = QueryUtils.taskQuery().taskId(taskId).singleResult(); |
| | | if (task == null) { |
| | | throw new ServiceException("ä»»å¡ä¸åå¨"); |
| | | } |
| | | MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); |
| | | if (multiInstance == null) { |
| | | return ""; |
| | | } |
| | | List<Long> userIds; |
| | | if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) { |
| | | userIds = (List<Long>) runtimeService.getVariable(task.getExecutionId(), multiInstance.getAssigneeList()); |
| | | } else { |
| | | List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list(); |
| | | userIds = StreamUtils.toList(list, e -> Long.valueOf(e.getAssignee())); |
| | | } |
| | | return StringUtils.join(userIds, StringUtils.SEPARATOR); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµéæ©åç¾äººå |
| | | * |
| | | * @param taskId ä»»å¡id ä»»å¡id |
| | | */ |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public List<TaskVo> getListByDeleteMultiInstance(String taskId) { |
| | | Task task = QueryUtils.taskQuery().taskId(taskId).singleResult(); |
| | | List<Task> taskList = QueryUtils.taskQuery(task.getProcessInstanceId()).list(); |
| | | MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); |
| | | List<TaskVo> taskListVo = new ArrayList<>(); |
| | | if (multiInstance == null) { |
| | | return List.of(); |
| | | } |
| | | List<Long> assigneeList = new ArrayList<>(); |
| | | if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) { |
| | | List<Object> variable = (List<Object>) runtimeService.getVariable(task.getExecutionId(), multiInstance.getAssigneeList()); |
| | | for (Object o : variable) { |
| | | assigneeList.add(Long.valueOf(o.toString())); |
| | | } |
| | | } |
| | | |
| | | if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) { |
| | | List<Long> userIds = StreamUtils.filter(assigneeList, e -> !String.valueOf(e).equals(task.getAssignee())); |
| | | List<UserDTO> userList = userService.selectListByIds(userIds); |
| | | for (Long userId : userIds) { |
| | | TaskVo taskVo = new TaskVo(); |
| | | taskVo.setId("串è¡ä¼ç¾"); |
| | | taskVo.setExecutionId("串è¡ä¼ç¾"); |
| | | taskVo.setProcessInstanceId(task.getProcessInstanceId()); |
| | | taskVo.setName(task.getName()); |
| | | taskVo.setAssignee(userId); |
| | | if (CollUtil.isNotEmpty(userList)) { |
| | | userList.stream().filter(u -> u.getUserId().toString().equals(userId.toString())).findFirst().ifPresent(u -> taskVo.setAssigneeName(u.getNickName())); |
| | | } |
| | | taskListVo.add(taskVo); |
| | | } |
| | | return taskListVo; |
| | | } else if (multiInstance.getType() instanceof ParallelMultiInstanceBehavior) { |
| | | List<Task> tasks = StreamUtils.filter(taskList, e -> StringUtils.isBlank(e.getParentTaskId()) && !e.getExecutionId().equals(task.getExecutionId()) && e.getTaskDefinitionKey().equals(task.getTaskDefinitionKey())); |
| | | if (CollUtil.isNotEmpty(tasks)) { |
| | | List<Long> userIds = StreamUtils.toList(tasks, e -> Long.valueOf(e.getAssignee())); |
| | | List<UserDTO> userList = userService.selectListByIds(userIds); |
| | | for (Task t : tasks) { |
| | | TaskVo taskVo = new TaskVo(); |
| | | taskVo.setId(t.getId()); |
| | | taskVo.setExecutionId(t.getExecutionId()); |
| | | taskVo.setProcessInstanceId(t.getProcessInstanceId()); |
| | | taskVo.setName(t.getName()); |
| | | taskVo.setAssignee(Long.valueOf(t.getAssignee())); |
| | | if (CollUtil.isNotEmpty(userList)) { |
| | | userList.stream().filter(u -> u.getUserId().toString().equals(t.getAssignee())).findFirst().ifPresent(e -> taskVo.setAssigneeName(e.getNickName())); |
| | | } |
| | | taskListVo.add(taskVo); |
| | | } |
| | | return taskListVo; |
| | | } |
| | | } |
| | | return List.of(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.workflow.domain.TestLeave; |
| | | import org.dromara.workflow.domain.bo.TestLeaveBo; |
| | | import org.dromara.workflow.domain.vo.TestLeaveVo; |
| | | import org.dromara.workflow.mapper.TestLeaveMapper; |
| | | import org.dromara.workflow.service.IActProcessInstanceService; |
| | | import org.dromara.workflow.service.ITestLeaveService; |
| | | import org.dromara.workflow.utils.WorkflowUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 请åServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2023-07-21 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class TestLeaveServiceImpl implements ITestLeaveService { |
| | | |
| | | private final TestLeaveMapper baseMapper; |
| | | private final IActProcessInstanceService actProcessInstanceService; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·å |
| | | */ |
| | | @Override |
| | | public TestLeaveVo queryById(Long id) { |
| | | TestLeaveVo testLeaveVo = baseMapper.selectVoById(id); |
| | | WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(id)); |
| | | return testLeaveVo; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·åå表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<TestLeaveVo> queryPageList(TestLeaveBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<TestLeave> lqw = buildQueryWrapper(bo); |
| | | Page<TestLeaveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | TableDataInfo<TestLeaveVo> build = TableDataInfo.build(result); |
| | | List<TestLeaveVo> rows = build.getRows(); |
| | | if (CollUtil.isNotEmpty(rows)) { |
| | | List<String> ids = StreamUtils.toList(rows, e -> String.valueOf(e.getId())); |
| | | WorkflowUtils.setProcessInstanceListVo(rows, ids, "id"); |
| | | } |
| | | return build; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯·åå表 |
| | | */ |
| | | @Override |
| | | public List<TestLeaveVo> queryList(TestLeaveBo bo) { |
| | | LambdaQueryWrapper<TestLeave> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<TestLeave> buildQueryWrapper(TestLeaveBo bo) { |
| | | LambdaQueryWrapper<TestLeave> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getLeaveType()), TestLeave::getLeaveType, bo.getLeaveType()); |
| | | lqw.ge(bo.getStartLeaveDays() != null, TestLeave::getLeaveDays, bo.getStartLeaveDays()); |
| | | lqw.le(bo.getEndLeaveDays() != null, TestLeave::getLeaveDays, bo.getEndLeaveDays()); |
| | | lqw.orderByDesc(BaseEntity::getCreateTime); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è¯·å |
| | | */ |
| | | @Override |
| | | public TestLeaveVo insertByBo(TestLeaveBo bo) { |
| | | TestLeave add = MapstructUtils.convert(bo, TestLeave.class); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | TestLeaveVo testLeaveVo = MapstructUtils.convert(add, TestLeaveVo.class); |
| | | WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(add.getId())); |
| | | return testLeaveVo; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹è¯·å |
| | | */ |
| | | @Override |
| | | public TestLeaveVo updateByBo(TestLeaveBo bo) { |
| | | TestLeave update = MapstructUtils.convert(bo, TestLeave.class); |
| | | baseMapper.updateById(update); |
| | | TestLeaveVo testLeaveVo = MapstructUtils.convert(update, TestLeaveVo.class); |
| | | WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(update.getId())); |
| | | return testLeaveVo; |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤è¯·å |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids) { |
| | | List<String> idList = StreamUtils.toList(ids, String::valueOf); |
| | | actProcessInstanceService.deleteRunAndHisInstanceByBusinessKeys(idList); |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.workflow.domain.WfCategory; |
| | | import org.dromara.workflow.domain.bo.WfCategoryBo; |
| | | import org.dromara.workflow.domain.vo.WfCategoryVo; |
| | | import org.dromara.workflow.mapper.WfCategoryMapper; |
| | | import org.dromara.workflow.service.IWfCategoryService; |
| | | import org.dromara.workflow.utils.QueryUtils; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.repository.Deployment; |
| | | import org.flowable.engine.repository.Model; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æµç¨åç±»Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2023-06-28 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfCategoryServiceImpl implements IWfCategoryService { |
| | | |
| | | private final WfCategoryMapper baseMapper; |
| | | |
| | | private final RepositoryService repositoryService; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±» |
| | | */ |
| | | @Override |
| | | public WfCategoryVo queryById(Long id) { |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»å表 |
| | | */ |
| | | @Override |
| | | public List<WfCategoryVo> queryList(WfCategoryBo bo) { |
| | | LambdaQueryWrapper<WfCategory> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<WfCategory> buildQueryWrapper(WfCategoryBo bo) { |
| | | LambdaQueryWrapper<WfCategory> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), WfCategory::getCategoryName, bo.getCategoryName()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getCategoryCode()), WfCategory::getCategoryCode, bo.getCategoryCode()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨åç±» |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(WfCategoryBo bo) { |
| | | WfCategory add = MapstructUtils.convert(bo, WfCategory.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹æµç¨åç±» |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean updateByBo(WfCategoryBo bo) { |
| | | WfCategory update = MapstructUtils.convert(bo, WfCategory.class); |
| | | validEntityBeforeSave(update); |
| | | WfCategoryVo wfCategoryVo = baseMapper.selectVoById(bo.getId()); |
| | | List<ProcessDefinition> processDefinitionList = QueryUtils.definitionQuery().processDefinitionCategory(wfCategoryVo.getCategoryCode()).list(); |
| | | for (ProcessDefinition processDefinition : processDefinitionList) { |
| | | repositoryService.setProcessDefinitionCategory(processDefinition.getId(), bo.getCategoryCode()); |
| | | } |
| | | List<Deployment> deploymentList = QueryUtils.deploymentQuery().deploymentCategory(wfCategoryVo.getCategoryCode()).list(); |
| | | for (Deployment deployment : deploymentList) { |
| | | repositoryService.setDeploymentCategory(deployment.getId(), bo.getCategoryCode()); |
| | | } |
| | | List<Model> modelList = QueryUtils.modelQuery().modelCategory(wfCategoryVo.getCategoryCode()).list(); |
| | | for (Model model : modelList) { |
| | | model.setCategory(bo.getCategoryCode()); |
| | | repositoryService.saveModel(model); |
| | | } |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(WfCategory entity) { |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå 餿µç¨åç±» |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if (isValid) { |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | /** |
| | | * æç
§ç±»å«ç¼ç æ¥è¯¢ |
| | | * |
| | | * @param categoryCode åç±»æ¯å |
| | | */ |
| | | @Override |
| | | public WfCategory queryByCategoryCode(String categoryCode) { |
| | | return baseMapper.selectOne(new LambdaQueryWrapper<WfCategory>().eq(WfCategory::getCategoryCode, categoryCode)); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.workflow.domain.WfDefinitionConfig; |
| | | import org.dromara.workflow.domain.bo.WfDefinitionConfigBo; |
| | | import org.dromara.workflow.domain.vo.WfDefinitionConfigVo; |
| | | import org.dromara.workflow.service.IWfDefinitionConfigService; |
| | | import org.springframework.stereotype.Service; |
| | | import org.dromara.workflow.mapper.WfDefinitionConfigMapper; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * æµç¨å®ä¹é
ç½®Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-18 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfDefinitionConfigServiceImpl implements IWfDefinitionConfigService { |
| | | |
| | | private final WfDefinitionConfigMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | */ |
| | | @Override |
| | | public WfDefinitionConfigVo getByDefId(String definitionId) { |
| | | return baseMapper.selectVoOne(new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getDefinitionId, definitionId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param tableName 表å |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public WfDefinitionConfigVo getByTableNameLastVersion(String tableName) { |
| | | List<WfDefinitionConfigVo> wfDefinitionConfigVos = baseMapper.selectVoList( |
| | | new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getTableName, tableName).orderByDesc(WfDefinitionConfig::getVersion)); |
| | | if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) { |
| | | return wfDefinitionConfigVos.get(0); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½® |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param tableName 表å |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public WfDefinitionConfigVo getByDefIdAndTableName(String definitionId, String tableName) { |
| | | return baseMapper.selectVoOne(new LambdaQueryWrapper<WfDefinitionConfig>() |
| | | .eq(WfDefinitionConfig::getDefinitionId, definitionId) |
| | | .eq(WfDefinitionConfig::getTableName, tableName)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½®æé¤å½åæ¥è¯¢çæµç¨å®ä¹ |
| | | * |
| | | * @param tableName 表å |
| | | * @param definitionId æµç¨å®ä¹id |
| | | */ |
| | | @Override |
| | | public List<WfDefinitionConfigVo> getByTableNameNotDefId(String tableName, String definitionId) { |
| | | return baseMapper.selectVoList(new LambdaQueryWrapper<WfDefinitionConfig>() |
| | | .eq(WfDefinitionConfig::getTableName, tableName) |
| | | .ne(WfDefinitionConfig::getDefinitionId, definitionId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹é
ç½®å表 |
| | | */ |
| | | @Override |
| | | public List<WfDefinitionConfigVo> queryList(List<String> definitionIds) { |
| | | return baseMapper.selectVoList(new LambdaQueryWrapper<WfDefinitionConfig>().in(WfDefinitionConfig::getDefinitionId, definitionIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢æµç¨å®ä¹é
ç½® |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean saveOrUpdate(WfDefinitionConfigBo bo) { |
| | | WfDefinitionConfig add = MapstructUtils.convert(bo, WfDefinitionConfig.class); |
| | | baseMapper.delete(new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getTableName, bo.getTableName())); |
| | | add.setTableName(add.getTableName().toLowerCase()); |
| | | boolean flag = baseMapper.insertOrUpdate(add); |
| | | if (baseMapper.insertOrUpdate(add)) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå 餿µç¨å®ä¹é
ç½® |
| | | */ |
| | | @Override |
| | | public Boolean deleteByIds(Collection<Long> ids) { |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean deleteByDefIds(Collection<String> ids) { |
| | | return baseMapper.delete(new LambdaQueryWrapper<WfDefinitionConfig>().in(WfDefinitionConfig::getDefinitionId, ids)) > 0; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.workflow.common.enums.FormTypeEnum; |
| | | import org.springframework.stereotype.Service; |
| | | import org.dromara.workflow.domain.bo.WfFormManageBo; |
| | | import org.dromara.workflow.domain.vo.WfFormManageVo; |
| | | import org.dromara.workflow.domain.WfFormManage; |
| | | import org.dromara.workflow.mapper.WfFormManageMapper; |
| | | import org.dromara.workflow.service.IWfFormManageService; |
| | | |
| | | import java.util.List; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * 表å管çServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-29 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfFormManageServiceImpl implements IWfFormManageService { |
| | | |
| | | private final WfFormManageMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管ç |
| | | */ |
| | | @Override |
| | | public WfFormManageVo queryById(Long id) { |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfFormManageVo> queryByIds(List<Long> ids) { |
| | | return baseMapper.selectVoBatchIds(ids); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<WfFormManageVo> queryPageList(WfFormManageBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<WfFormManage> lqw = buildQueryWrapper(bo); |
| | | Page<WfFormManageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | @Override |
| | | public List<WfFormManageVo> selectList() { |
| | | List<WfFormManageVo> wfFormManageVos = baseMapper.selectVoList(new LambdaQueryWrapper<WfFormManage>().orderByDesc(WfFormManage::getUpdateTime)); |
| | | for (WfFormManageVo wfFormManageVo : wfFormManageVos) { |
| | | wfFormManageVo.setFormTypeName(FormTypeEnum.findByType(wfFormManageVo.getFormType())); |
| | | } |
| | | return wfFormManageVos; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢è¡¨å管çå表 |
| | | */ |
| | | @Override |
| | | public List<WfFormManageVo> queryList(WfFormManageBo bo) { |
| | | LambdaQueryWrapper<WfFormManage> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<WfFormManage> buildQueryWrapper(WfFormManageBo bo) { |
| | | LambdaQueryWrapper<WfFormManage> lqw = Wrappers.lambdaQuery(); |
| | | lqw.like(StringUtils.isNotBlank(bo.getFormName()), WfFormManage::getFormName, bo.getFormName()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getFormType()), WfFormManage::getFormType, bo.getFormType()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è¡¨å管ç |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(WfFormManageBo bo) { |
| | | WfFormManage add = MapstructUtils.convert(bo, WfFormManage.class); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹è¡¨å管ç |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(WfFormManageBo bo) { |
| | | WfFormManage update = MapstructUtils.convert(bo, WfFormManage.class); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤è¡¨å管ç |
| | | */ |
| | | @Override |
| | | public Boolean deleteByIds(Collection<Long> ids) { |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.workflow.domain.vo.WfFormManageVo; |
| | | import org.dromara.workflow.service.IWfFormManageService; |
| | | import org.springframework.stereotype.Service; |
| | | import org.dromara.workflow.domain.vo.WfNodeConfigVo; |
| | | import org.dromara.workflow.domain.WfNodeConfig; |
| | | import org.dromara.workflow.mapper.WfNodeConfigMapper; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * èç¹é
ç½®Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-30 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfNodeConfigServiceImpl implements IWfNodeConfigService { |
| | | |
| | | private final WfNodeConfigMapper baseMapper; |
| | | private final IWfFormManageService wfFormManageService; |
| | | |
| | | /** |
| | | * æ¥è¯¢èç¹é
ç½® |
| | | */ |
| | | @Override |
| | | public WfNodeConfigVo queryById(Long id) { |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | /** |
| | | * ä¿åèç¹é
ç½® |
| | | */ |
| | | @Override |
| | | public Boolean saveOrUpdate(List<WfNodeConfig> list) { |
| | | return baseMapper.insertOrUpdateBatch(list); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤èç¹é
ç½® |
| | | */ |
| | | @Override |
| | | public Boolean deleteByIds(Collection<Long> ids) { |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public Boolean deleteByDefIds(Collection<String> ids) { |
| | | return baseMapper.delete(new LambdaQueryWrapper<WfNodeConfig>().in(WfNodeConfig::getDefinitionId, ids)) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public List<WfNodeConfigVo> selectByDefIds(Collection<String> ids) { |
| | | List<WfNodeConfigVo> wfNodeConfigVos = baseMapper.selectVoList(new LambdaQueryWrapper<WfNodeConfig>().in(WfNodeConfig::getDefinitionId, ids)); |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVos)) { |
| | | List<Long> formIds = StreamUtils.toList(wfNodeConfigVos, WfNodeConfigVo::getFormId); |
| | | List<WfFormManageVo> wfFormManageVos = wfFormManageService.queryByIds(formIds); |
| | | for (WfNodeConfigVo wfNodeConfigVo : wfNodeConfigVos) { |
| | | wfFormManageVos.stream().filter(e -> ObjectUtil.equals(e.getId(), wfNodeConfigVo.getFormId())).findFirst().ifPresent(wfNodeConfigVo::setWfFormManageVo); |
| | | } |
| | | } |
| | | return wfNodeConfigVos; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.workflow.domain.WfTaskBackNode; |
| | | import org.dromara.workflow.domain.vo.MultiInstanceVo; |
| | | import org.dromara.workflow.mapper.WfTaskBackNodeMapper; |
| | | import org.dromara.workflow.service.IWfTaskBackNodeService; |
| | | import org.dromara.workflow.utils.WorkflowUtils; |
| | | import org.flowable.task.api.Task; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import static org.dromara.workflow.common.constant.FlowConstant.MULTI_INSTANCE; |
| | | import static org.dromara.workflow.common.constant.FlowConstant.USER_TASK; |
| | | |
| | | |
| | | /** |
| | | * èç¹é©³åè®°å½Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author may |
| | | * @date 2024-03-13 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class WfTaskBackNodeServiceImpl implements IWfTaskBackNodeService { |
| | | |
| | | private final WfTaskBackNodeMapper wfTaskBackNodeMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void recordExecuteNode(Task task) { |
| | | List<WfTaskBackNode> list = getListByInstanceId(task.getProcessInstanceId()); |
| | | WfTaskBackNode wfTaskBackNode = new WfTaskBackNode(); |
| | | wfTaskBackNode.setNodeId(task.getTaskDefinitionKey()); |
| | | wfTaskBackNode.setNodeName(task.getName()); |
| | | wfTaskBackNode.setInstanceId(task.getProcessInstanceId()); |
| | | wfTaskBackNode.setAssignee(String.valueOf(LoginHelper.getUserId())); |
| | | MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); |
| | | if (ObjectUtil.isNotEmpty(multiInstance)) { |
| | | wfTaskBackNode.setTaskType(MULTI_INSTANCE); |
| | | } else { |
| | | wfTaskBackNode.setTaskType(USER_TASK); |
| | | } |
| | | if (CollUtil.isEmpty(list)) { |
| | | wfTaskBackNode.setOrderNo(0); |
| | | wfTaskBackNodeMapper.insert(wfTaskBackNode); |
| | | } else { |
| | | WfTaskBackNode taskNode = list.stream().filter(e -> e.getNodeId().equals(wfTaskBackNode.getNodeId()) && e.getOrderNo() == 0).findFirst().orElse(null); |
| | | if (ObjectUtil.isEmpty(taskNode)) { |
| | | wfTaskBackNode.setOrderNo(list.get(0).getOrderNo() + 1); |
| | | WfTaskBackNode node = getListByInstanceIdAndNodeId(wfTaskBackNode.getInstanceId(), wfTaskBackNode.getNodeId()); |
| | | if (ObjectUtil.isNotEmpty(node)) { |
| | | node.setAssignee(node.getAssignee() + StringUtils.SEPARATOR + LoginHelper.getUserId()); |
| | | wfTaskBackNodeMapper.updateById(node); |
| | | } else { |
| | | wfTaskBackNodeMapper.insert(wfTaskBackNode); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<WfTaskBackNode> getListByInstanceId(String processInstanceId) { |
| | | LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId); |
| | | wrapper.orderByDesc(WfTaskBackNode::getOrderNo); |
| | | return wfTaskBackNodeMapper.selectList(wrapper); |
| | | } |
| | | |
| | | @Override |
| | | public WfTaskBackNode getListByInstanceIdAndNodeId(String processInstanceId, String nodeId) { |
| | | LambdaQueryWrapper<WfTaskBackNode> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId); |
| | | queryWrapper.eq(WfTaskBackNode::getNodeId, nodeId); |
| | | return wfTaskBackNodeMapper.selectOne(queryWrapper); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteBackTaskNode(String processInstanceId, String targetActivityId) { |
| | | try { |
| | | LambdaQueryWrapper<WfTaskBackNode> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId); |
| | | queryWrapper.eq(WfTaskBackNode::getNodeId, targetActivityId); |
| | | WfTaskBackNode actTaskNode = wfTaskBackNodeMapper.selectOne(queryWrapper); |
| | | if (ObjectUtil.isNotNull(actTaskNode)) { |
| | | Integer orderNo = actTaskNode.getOrderNo(); |
| | | List<WfTaskBackNode> taskNodeList = getListByInstanceId(processInstanceId); |
| | | List<Long> ids = new ArrayList<>(); |
| | | if (CollUtil.isNotEmpty(taskNodeList)) { |
| | | for (WfTaskBackNode taskNode : taskNodeList) { |
| | | if (taskNode.getOrderNo() >= orderNo) { |
| | | ids.add(taskNode.getId()); |
| | | } |
| | | } |
| | | } |
| | | if (CollUtil.isNotEmpty(ids)) { |
| | | wfTaskBackNodeMapper.deleteBatchIds(ids); |
| | | } |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException("å é¤å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteByInstanceId(String processInstanceId) { |
| | | LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId); |
| | | List<WfTaskBackNode> list = wfTaskBackNodeMapper.selectList(wrapper); |
| | | int delete = wfTaskBackNodeMapper.delete(wrapper); |
| | | if (list.size() != delete) { |
| | | throw new ServiceException("å é¤å¤±è´¥"); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean deleteByInstanceIds(List<String> processInstanceIds) { |
| | | LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.in(WfTaskBackNode::getInstanceId, processInstanceIds); |
| | | List<WfTaskBackNode> list = wfTaskBackNodeMapper.selectList(wrapper); |
| | | int delete = wfTaskBackNodeMapper.delete(wrapper); |
| | | if (list.size() != delete) { |
| | | throw new ServiceException("å é¤å¤±è´¥"); |
| | | } |
| | | return true; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.workflow.domain.vo.MultiInstanceVo; |
| | | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.editor.language.json.converter.BpmnJsonConverter; |
| | | import org.flowable.engine.ProcessEngine; |
| | | |
| | | import javax.xml.stream.XMLInputFactory; |
| | | import javax.xml.stream.XMLStreamException; |
| | | import javax.xml.stream.XMLStreamReader; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.rmi.ServerException; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 模åå·¥å
· |
| | | * |
| | | * @author may |
| | | */ |
| | | @NoArgsConstructor(access = AccessLevel.PRIVATE) |
| | | public class ModelUtils { |
| | | |
| | | private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class); |
| | | |
| | | public static BpmnModel xmlToBpmnModel(String xml) throws IOException { |
| | | if (xml == null) { |
| | | throw new ServerException("xmlä¸è½ä¸ºç©º"); |
| | | } |
| | | try { |
| | | InputStream inputStream = new ByteArrayInputStream(StrUtil.utf8Bytes(xml)); |
| | | XMLInputFactory factory = XMLInputFactory.newInstance(); |
| | | XMLStreamReader reader = factory.createXMLStreamReader(inputStream); |
| | | return new BpmnXMLConverter().convertToBpmnModel(reader); |
| | | } catch (XMLStreamException e) { |
| | | throw new ServerException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * bpmnModel转为xml |
| | | * |
| | | * @param jsonBytes json |
| | | */ |
| | | public static byte[] bpmnJsonToXmlBytes(byte[] jsonBytes) throws IOException { |
| | | if (jsonBytes == null) { |
| | | return new byte[0]; |
| | | } |
| | | // 1. jsonåèç 转æ BpmnModel 对象 |
| | | ObjectMapper objectMapper = JsonUtils.getObjectMapper(); |
| | | JsonNode jsonNode = objectMapper.readTree(jsonBytes); |
| | | BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode); |
| | | |
| | | if (bpmnModel.getProcesses().isEmpty()) { |
| | | return new byte[0]; |
| | | } |
| | | // 2.å°bpmnModel转为xml |
| | | return new BpmnXMLConverter().convertToXML(bpmnModel); |
| | | } |
| | | |
| | | /** |
| | | * xml转为bpmnModel |
| | | * |
| | | * @param xmlBytes xml |
| | | */ |
| | | public static BpmnModel xmlToBpmnModel(byte[] xmlBytes) throws XMLStreamException { |
| | | ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(xmlBytes); |
| | | XMLInputFactory xif = XMLInputFactory.newInstance(); |
| | | XMLStreamReader xtr = xif.createXMLStreamReader(byteArrayInputStream); |
| | | return new BpmnXMLConverter().convertToBpmnModel(xtr); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªæ¨¡å |
| | | * |
| | | * @param bpmnModel bpmn模å |
| | | */ |
| | | public static void checkBpmnModel(BpmnModel bpmnModel) throws ServerException { |
| | | Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements(); |
| | | |
| | | checkBpmnNode(flowElements, false); |
| | | |
| | | List<SubProcess> subProcessList = flowElements.stream().filter(SubProcess.class::isInstance).map(SubProcess.class::cast).collect(Collectors.toList()); |
| | | if (!CollUtil.isEmpty(subProcessList)) { |
| | | for (SubProcess subProcess : subProcessList) { |
| | | Collection<FlowElement> subProcessFlowElements = subProcess.getFlowElements(); |
| | | checkBpmnNode(subProcessFlowElements, true); |
| | | } |
| | | } |
| | | List<MultiInstanceVo> multiInstanceVoList = new ArrayList<>(); |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof UserTask && ObjectUtil.isNotEmpty(((UserTask) flowElement).getLoopCharacteristics()) && StringUtils.isNotBlank(((UserTask) flowElement).getLoopCharacteristics().getInputDataItem())) { |
| | | MultiInstanceVo multiInstanceVo = new MultiInstanceVo(); |
| | | multiInstanceVo.setAssigneeList(((UserTask) flowElement).getLoopCharacteristics().getInputDataItem()); |
| | | multiInstanceVoList.add(multiInstanceVo); |
| | | } |
| | | } |
| | | |
| | | if (CollectionUtil.isNotEmpty(multiInstanceVoList) && multiInstanceVoList.size() > 1) { |
| | | Map<String, List<MultiInstanceVo>> assigneeListGroup = StreamUtils.groupByKey(multiInstanceVoList, MultiInstanceVo::getAssigneeList); |
| | | for (Map.Entry<String, List<MultiInstanceVo>> entry : assigneeListGroup.entrySet()) { |
| | | List<MultiInstanceVo> value = entry.getValue(); |
| | | if (CollectionUtil.isNotEmpty(value) && value.size() > 1) { |
| | | String key = entry.getKey(); |
| | | throw new ServerException("ä¼ç¾äººåéåã" + key + "ãéå¤,è¯·éæ°è®¾ç½®éåKEY"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªbpmnèç¹æ¯å¦åæ³ |
| | | * |
| | | * @param flowElements èç¹éå |
| | | * @param subtask æ¯å¦åæµç¨ |
| | | */ |
| | | private static void checkBpmnNode(Collection<FlowElement> flowElements, boolean subtask) throws ServerException { |
| | | |
| | | if (CollUtil.isEmpty(flowElements)) { |
| | | throw new ServerException(subtask ? "åæµç¨å¿
é¡»åå¨èç¹" : "å¿
é¡»åå¨èç¹ï¼"); |
| | | } |
| | | |
| | | List<StartEvent> startEventList = flowElements.stream().filter(StartEvent.class::isInstance).map(StartEvent.class::cast).collect(Collectors.toList()); |
| | | if (CollUtil.isEmpty(startEventList)) { |
| | | throw new ServerException(subtask ? "åæµç¨å¿
é¡»åå¨å¼å§èç¹" : "å¿
é¡»åå¨å¼å§èç¹ï¼"); |
| | | } |
| | | |
| | | if (startEventList.size() > 1) { |
| | | throw new ServerException(subtask ? "åæµç¨åªè½åå¨ä¸ä¸ªå¼å§èç¹" : "åªè½åå¨ä¸ä¸ªå¼å§èç¹ï¼"); |
| | | } |
| | | |
| | | StartEvent startEvent = startEventList.get(0); |
| | | List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows(); |
| | | if (CollUtil.isEmpty(outgoingFlows)) { |
| | | throw new ServerException(subtask ? "åæµç¨æµç¨èç¹ä¸ºç©ºï¼è¯·è³å°è®¾è®¡ä¸æ¡ä¸»çº¿æµç¨ï¼" : "æµç¨èç¹ä¸ºç©ºï¼è¯·è³å°è®¾è®¡ä¸æ¡ä¸»çº¿æµç¨ï¼"); |
| | | } |
| | | |
| | | FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement(); |
| | | if (!(targetFlowElement instanceof UserTask) && !subtask) { |
| | | throw new ServerException("å¼å§èç¹å第ä¸ä¸ªèç¹å¿
é¡»æ¯ç¨æ·ä»»å¡ï¼"); |
| | | } |
| | | //å¼å§èç¹å第ä¸ä¸ªèç¹ç³è¯·äººèç¹ |
| | | if ((targetFlowElement instanceof UserTask) && !subtask) { |
| | | UserTask userTask = (UserTask) targetFlowElement; |
| | | if (StringUtils.isBlank(userTask.getFormKey())) { |
| | | throw new ServerException("ç³è¯·äººèç¹å¿
é¡»éæ©è¡¨åï¼"); |
| | | } |
| | | } |
| | | List<EndEvent> endEventList = flowElements.stream().filter(EndEvent.class::isInstance).map(EndEvent.class::cast).collect(Collectors.toList()); |
| | | if (CollUtil.isEmpty(endEventList)) { |
| | | throw new ServerException(subtask ? "åæµç¨å¿
é¡»åå¨ç»æèç¹ï¼" : "å¿
é¡»åå¨ç»æèç¹ï¼"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨å
¨é¨ç¨æ·èç¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | public static List<UserTask> getUserTaskFlowElements(String processDefinitionId) { |
| | | BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId); |
| | | List<UserTask> list = new ArrayList<>(); |
| | | List<Process> processes = bpmnModel.getProcesses(); |
| | | Collection<FlowElement> flowElements = processes.get(0).getFlowElements(); |
| | | buildUserTaskFlowElements(flowElements, list); |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * éå½è·åææèç¹ |
| | | * |
| | | * @param flowElements èç¹ä¿¡æ¯ |
| | | * @param list éå |
| | | */ |
| | | private static void buildUserTaskFlowElements(Collection<FlowElement> flowElements, List<UserTask> list) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof SubProcess) { |
| | | Collection<FlowElement> subFlowElements = ((SubProcess) flowElement).getFlowElements(); |
| | | buildUserTaskFlowElements(subFlowElements, list); |
| | | } else if (flowElement instanceof UserTask) { |
| | | list.add((UserTask) flowElement); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åæµç¨å
¨é¨èç¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | public static List<FlowElement> getFlowElements(String processDefinitionId) { |
| | | BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId); |
| | | List<FlowElement> list = new ArrayList<>(); |
| | | List<Process> processes = bpmnModel.getProcesses(); |
| | | Collection<FlowElement> flowElements = processes.get(0).getFlowElements(); |
| | | buildFlowElements(flowElements, list); |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * éå½è·åææèç¹ |
| | | * |
| | | * @param flowElements èç¹ä¿¡æ¯ |
| | | * @param list éå |
| | | */ |
| | | private static void buildFlowElements(Collection<FlowElement> flowElements, List<FlowElement> list) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | list.add(flowElement); |
| | | if (flowElement instanceof SubProcess) { |
| | | Collection<FlowElement> subFlowElements = ((SubProcess) flowElement).getFlowElements(); |
| | | buildFlowElements(subFlowElements, list); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åå
¨é¨æ©å±ä¿¡æ¯ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | */ |
| | | public static Map<String, List<ExtensionElement>> getExtensionElements(String processDefinitionId) { |
| | | Map<String, List<ExtensionElement>> map = new HashMap<>(); |
| | | List<FlowElement> flowElements = getFlowElements(processDefinitionId); |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof UserTask && CollUtil.isNotEmpty(flowElement.getExtensionElements())) { |
| | | map.putAll(flowElement.getExtensionElements()); |
| | | } |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * è·åæä¸ªèç¹çæ©å±ä¿¡æ¯ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @param flowElementId èç¹id |
| | | */ |
| | | public static Map<String, List<ExtensionElement>> getExtensionElement(String processDefinitionId, String flowElementId) { |
| | | BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId); |
| | | Process process = bpmnModel.getMainProcess(); |
| | | FlowElement flowElement = process.getFlowElement(flowElementId); |
| | | return flowElement.getExtensionElements(); |
| | | } |
| | | |
| | | /** |
| | | * 夿å½åèç¹æ¯å¦ä¸ºç¨æ·ä»»å¡ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @param taskDefinitionKey æµç¨å®ä¹id |
| | | */ |
| | | public static boolean isUserTask(String processDefinitionId, String taskDefinitionKey) { |
| | | BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId); |
| | | FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey); |
| | | return flowNode instanceof UserTask; |
| | | } |
| | | |
| | | /** |
| | | * è·åç³è¯·äººèç¹ |
| | | * |
| | | * @param processDefinitionId æµç¨å®ä¹id |
| | | * @return ç»æ |
| | | */ |
| | | public static UserTask getApplyUserTask(String processDefinitionId) { |
| | | BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId); |
| | | Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements(); |
| | | List<StartEvent> startEventList = flowElements.stream().filter(StartEvent.class::isInstance).map(StartEvent.class::cast).collect(Collectors.toList()); |
| | | StartEvent startEvent = startEventList.get(0); |
| | | List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows(); |
| | | FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement(); |
| | | return (UserTask) targetFlowElement; |
| | | } |
| | | } |
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/QueryUtils.java
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/package-info.md
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiProcinstMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiTaskinstMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActTaskMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/TestLeaveMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfCategoryMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfDefinitionConfigMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfFormManageMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfNodeConfigMapper.xml
ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfTaskBackNodeMapper.xml
script/bin/ry.bat
script/bin/ry.sh
script/bpmn/模型.zip
script/docker/docker-compose.yml
script/docker/nginx/conf/nginx.conf
script/sql/flowable.sql
script/sql/oracle/flowable.sql
script/sql/oracle/oracle_ry_vue_5.X.sql
script/sql/oracle/oracle_test.sql (已删除)
script/sql/oracle/powerjob.sql (已删除)
script/sql/oracle/snail_job_oracle.sql
script/sql/postgres/flowable.sql
script/sql/postgres/postgres_ry_vue_5.X.sql
script/sql/postgres/postgres_test.sql (已删除)
script/sql/postgres/powerjob.sql (已删除)
script/sql/postgres/snail_job_postgre.sql
script/sql/powerjob.sql (已删除)
script/sql/ry_vue_5.X.sql
script/sql/snail_job.sql
script/sql/sqlserver/flowable.sql
script/sql/sqlserver/powerjob.sql (已删除)
script/sql/sqlserver/snail_job_sqlserver.sql
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
script/sql/sqlserver/sqlserver_test.sql (已删除)
script/sql/test.sql (已删除)
script/sql/update/oracle/update_5.0-5.1.sql
script/sql/update/oracle/update_5.1.0-5.1.1.sql
script/sql/update/oracle/update_5.1.1-5.1.2.sql
script/sql/update/oracle/update_5.1.2-5.2.0.sql
script/sql/update/postgres/update_5.0-5.1.sql
script/sql/update/postgres/update_5.1.1-5.1.2.sql
script/sql/update/postgres/update_5.1.2-5.2.0.sql
script/sql/update/sqlserver/update_5.0-5.1.sql
script/sql/update/sqlserver/update_5.1.2-5.2.0.sql
script/sql/update/update_5.1.1-5.1.2.sql
script/sql/update/update_5.1.2-5.2.0.sql |