mirror of
https://gitee.com/zhijiantianya/ruoyi-vue-pro.git
synced 2026-06-28 10:16:12 +08:00
Compare commits
278 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15ba083de2 | |||
| 9a9dbf0e97 | |||
| 3c3919545a | |||
| 2980c6e3eb | |||
| 09cb5b6433 | |||
| 90390dfdfa | |||
| d1b6534886 | |||
| 972b386d93 | |||
| fc4b677b00 | |||
| 5c03b97775 | |||
| 500f0a72ce | |||
| 73e30a4f37 | |||
| 120cbc9123 | |||
| e5b711409c | |||
| 69b93ca75a | |||
| 6489047a7d | |||
| 1c6a77806b | |||
| cd919daf64 | |||
| d2636a7787 | |||
| f3e0ca27d9 | |||
| e2a9b2d3e5 | |||
| 3201288036 | |||
| b845d62e8b | |||
| bf37095259 | |||
| 5d90760c39 | |||
| 882660a3a7 | |||
| e90fc607f0 | |||
| ec8b356ba6 | |||
| c61811a622 | |||
| a49b1431e5 | |||
| 2af0e40fe7 | |||
| f63d4e20b9 | |||
| 2505d61b08 | |||
| fc509837a1 | |||
| 66d6825657 | |||
| c58eb12896 | |||
| 81d89ba350 | |||
| 0cbf35f7f0 | |||
| 4a86bd23d8 | |||
| 41cdc951e1 | |||
| 66ebb71b8a | |||
| c64bb81cae | |||
| e52d7d33be | |||
| 19cb2b69f1 | |||
| 80cdfbf36e | |||
| 10ba70e107 | |||
| 75928525ca | |||
| fa62ace6af | |||
| 95bb9744c1 | |||
| 848fcdf329 | |||
| d10b4595a2 | |||
| e4be51b14a | |||
| 4d53944771 | |||
| 124576005a | |||
| 7c42632a50 | |||
| 40e52c3856 | |||
| feeaac729c | |||
| 2598c033a9 | |||
| 6b6d676a6b | |||
| 79311ecc71 | |||
| 27c30279a1 | |||
| d8d81e835f | |||
| 72d18b056b | |||
| 1f08a2725e | |||
| e01acfb18e | |||
| 41e4283f99 | |||
| c1884c3196 | |||
| d30bf0601c | |||
| 075dd83b5f | |||
| d6775a5619 | |||
| 073d860a78 | |||
| c761f5258a | |||
| d64555697f | |||
| b1d6baaad8 | |||
| d6a6a01252 | |||
| a207412e8c | |||
| 9c452ee612 | |||
| 167baed952 | |||
| 8dc40224cc | |||
| 252b218c42 | |||
| 9be08aae63 | |||
| 121fd0652d | |||
| 9882142a46 | |||
| 822f4e8192 | |||
| 4efb6c0847 | |||
| 8eba07c736 | |||
| 9a9f7058ae | |||
| bcceac5df2 | |||
| 38614abe76 | |||
| f56450c6b7 | |||
| f7268e7ce4 | |||
| fe552aedcd | |||
| a3e8ee2b41 | |||
| 7d367c367c | |||
| 9724a522e9 | |||
| ca4290204c | |||
| fff6fedcfa | |||
| 1bebd5ef8e | |||
| 8e0415a8fe | |||
| 5036971f55 | |||
| d3c5906cfa | |||
| cfd8cd57cf | |||
| fad3a030e9 | |||
| 02a0ab6d6d | |||
| fee6d00ecf | |||
| b72aa7b268 | |||
| 38ac5270d6 | |||
| 433056d5ea | |||
| 250c56f90c | |||
| c0380aaf6a | |||
| eda8418797 | |||
| 69dba93ae5 | |||
| 3d09088029 | |||
| 1b2dc570de | |||
| f564137f05 | |||
| 63900da8c2 | |||
| 170c0dbcfc | |||
| 9626b5e971 | |||
| e1e749d8a4 | |||
| 5856c93035 | |||
| f749b9db06 | |||
| 5e959d310a | |||
| c414e0eb62 | |||
| 2ce2287146 | |||
| 9edf88b37a | |||
| 7e31efcfe2 | |||
| ab420e4120 | |||
| 7b7f285034 | |||
| 46056a16b4 | |||
| f34f28f576 | |||
| f1f602c131 | |||
| f736e0a1c4 | |||
| 969f9d0327 | |||
| 2579e8549e | |||
| ba74c587b7 | |||
| fc3aa2047c | |||
| ec378d75de | |||
| e03a1a8bb3 | |||
| 78fe38d687 | |||
| a6b70491e3 | |||
| 8b31b65ac1 | |||
| bc400cf646 | |||
| 4f5964f287 | |||
| 3cb7aba37e | |||
| c844c7ef19 | |||
| b267b2c347 | |||
| 08a35704e9 | |||
| 986d1328e0 | |||
| 4a8129bffa | |||
| 833ac54a2f | |||
| 7bf9a85263 | |||
| 7df42db2e2 | |||
| e3c31c353a | |||
| c06a96b768 | |||
| e7d0024eb0 | |||
| d44d4da428 | |||
| 471175b406 | |||
| 62cc1206f7 | |||
| a7a98d153c | |||
| 41c6aa9147 | |||
| 63b7ee096a | |||
| cff4391f2d | |||
| a7feb9279f | |||
| 4bf5b04d54 | |||
| c5fad966d2 | |||
| 1cc2e09185 | |||
| 1467ab6530 | |||
| 3ac2b9973c | |||
| 053007ef9e | |||
| 33d8dbef45 | |||
| 30f160446e | |||
| 4f770b24a4 | |||
| bc41aa70d1 | |||
| f540c8a37c | |||
| 20e34e35a3 | |||
| cfcc2c6762 | |||
| fe0886d122 | |||
| de4df784ea | |||
| b1d42becc3 | |||
| 878a0ef638 | |||
| c0bebb7755 | |||
| 32ccb8bd84 | |||
| 4c169cbc58 | |||
| 0d1a8c627b | |||
| 5dcf763f08 | |||
| fcbb99941c | |||
| efcff7333e | |||
| 128ee67925 | |||
| 28cb66b971 | |||
| bfe7cf01eb | |||
| 5e43efc555 | |||
| 67df00264a | |||
| 424ddb23e4 | |||
| 2cef84bdc8 | |||
| 152453106a | |||
| 55d8977108 | |||
| 3f19760678 | |||
| cd42846bec | |||
| 855bb214be | |||
| f0395c450f | |||
| 5151112912 | |||
| 37ec560687 | |||
| f966fae060 | |||
| fd4adf2cea | |||
| 2bc45ad467 | |||
| c671c23e87 | |||
| d5c35c23dc | |||
| 09d0634694 | |||
| 1044e1ac72 | |||
| 0bac283864 | |||
| 251bd08508 | |||
| 2dd4450302 | |||
| 448aa21e33 | |||
| d649b93017 | |||
| bb02c8eccc | |||
| 40d5eb4a07 | |||
| cb3b172ecc | |||
| 470d1a3a35 | |||
| 9f65c46c82 | |||
| ae9186f4b4 | |||
| 6441883855 | |||
| 1e2bcf9aca | |||
| 61672e0180 | |||
| eb2ab3cc4d | |||
| c2ccfa3bd6 | |||
| 4890cf05de | |||
| f2f36bd617 | |||
| 2177aea2bd | |||
| b85b33c373 | |||
| db9bae05b0 | |||
| 8e3d7663bb | |||
| 24e083b3ae | |||
| 0773a4c4d7 | |||
| 352a67c530 | |||
| b0c25ea9f4 | |||
| 8d59384904 | |||
| 2b630ef3f2 | |||
| bdcf00d8a0 | |||
| f39bfdab89 | |||
| fe1271a6f7 | |||
| 510917c5ed | |||
| d45213fe2a | |||
| b757e1fccb | |||
| e7e3b18704 | |||
| fffd023d31 | |||
| 9bc9b2ac6b | |||
| dc11dfc215 | |||
| 4bc8dc65b4 | |||
| 638b8b1dd4 | |||
| 14097b4120 | |||
| fd53bf3296 | |||
| 16c2590483 | |||
| add08b1ecd | |||
| ab6ec2f0ed | |||
| 933bb7c6a6 | |||
| c5e2df943c | |||
| 117914d92b | |||
| 06887bff16 | |||
| cee7e50720 | |||
| 6aca4ae9fd | |||
| 36d01371bb | |||
| e9efff7076 | |||
| 928b7dbe23 | |||
| afa0d623db | |||
| 1c266988c5 | |||
| 06fa85a353 | |||
| f8a0d1778a | |||
| 8bcdb8600c | |||
| 678e2def97 | |||
| 4ba064d8b3 | |||
| cb2ba6da2f | |||
| df141f2982 | |||
| 671c41bf82 | |||
| 21fbe91e39 | |||
| 5376ed69b1 | |||
| 5430cc292e | |||
| 08cfe71646 | |||
| 3f412f26fc |
30
.github/workflows/maven.yml
vendored
Normal file
30
.github/workflows/maven.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
# pull_request:
|
||||
# branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ '8', '11', '17' ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK ${{ matrix.Java }}
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: 'temurin'
|
||||
cache: maven
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml -Dmaven.test.skip=true
|
||||
51
.github/workflows/yudao-ui-admin.yml
vendored
Normal file
51
.github/workflows/yudao-ui-admin.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
name: yudao-ui-admin CI
|
||||
|
||||
# 在master分支发生push事件时触发。
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
# pull_request:
|
||||
# branches: [ master ]
|
||||
env: # 设置环境变量
|
||||
TZ: Asia/Shanghai # 时区(设置时区可使页面中的`最近更新时间`使用时区时间)
|
||||
WORK_DIR: yudao-ui-admin #工作目录
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: yudao-ui-admin
|
||||
|
||||
jobs:
|
||||
build: # 自定义名称
|
||||
runs-on: ubuntu-latest # 运行在虚拟机环境ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x, 16.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- name: Checkout # 步骤1
|
||||
uses: actions/checkout@v2 # 使用的动作。格式:userName/repoName。作用:检出仓库,获取源码。 官方actions库:https://github.com/actions
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2.0.1
|
||||
with:
|
||||
version: 6.15.1
|
||||
|
||||
- name: Set node version to ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: "yarn"
|
||||
cache-dependency-path: yudao-ui-admin/yarn.lock
|
||||
|
||||
- name: Install deps
|
||||
run: node --version && yarn --version && yarn install
|
||||
|
||||
- name: Build
|
||||
run: yarn build:prod
|
||||
|
||||
# 查看 workflow 的文档来获取更多信息
|
||||
# @see https://github.com/crazy-max/ghaction-github-pages
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,3 +43,5 @@ nbdist/
|
||||
!*/build/*.html
|
||||
!*/build/*.xml
|
||||
|
||||
### JRebel ###
|
||||
rebel.xml
|
||||
|
||||
109
README.md
109
README.md
@ -1,4 +1,11 @@
|
||||
## 平台简介
|
||||
**严肃声明:现在、未来都不会有商业版本,所有功能全部开源!**
|
||||
|
||||
**拒绝虚假开源,售卖商业版,程序员不骗程序员!!**
|
||||
|
||||
**「我喜欢写代码,乐此不疲」**
|
||||
**「我喜欢做开源,以此为乐」**
|
||||
|
||||
## 🐯 平台简介
|
||||
|
||||
**芋道**,一套**全部开源**的**企业级**的快速开发平台,毫无保留给个人及企业免费使用。
|
||||
|
||||
@ -8,12 +15,19 @@
|
||||
* 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson。
|
||||
* 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统。
|
||||
* 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能。
|
||||
* 支持 SaaS 多租户系统,可自定义每个租户的权限,提供透明化的多租户底层封装。
|
||||
* 工作流使用 Activiti ,支持动态表单、在线设计流程、多种任务分配方式。
|
||||
* 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验。
|
||||
* 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。
|
||||
* 集成阿里云、腾讯云、云片等短信渠道,集成阿里云、腾讯云、七牛云等云存储服务。
|
||||
|
||||
## 在线体验
|
||||
| 项目名 | 说明 | 传说门 |
|
||||
| ---- |------------------------| ---- |
|
||||
| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)** [Github](https://github.com/YunaiV/ruoyi-vue-pro) |
|
||||
| `ruoyi-vue-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-cloud)** [Github](https://github.com/YunaiV/onemall) |
|
||||
| `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)** [Github](https://github.com/YunaiV/SpringBoot-Labs) |
|
||||
|
||||
## 🐶 在线体验
|
||||
|
||||
演示地址:<http://dashboard.yudao.iocoder.cn>
|
||||
* 账号密码:admin/admin123
|
||||
@ -23,7 +37,7 @@
|
||||
|
||||
> 未来会补充文档和视频,方便胖友冲冲冲!
|
||||
|
||||
## 内置功能
|
||||
## 🐼 内置功能
|
||||
|
||||
分成多种内置功能:
|
||||
* 系统功能
|
||||
@ -51,6 +65,7 @@
|
||||
| | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 |
|
||||
| | 岗位管理 | 配置系统用户所属担任职务 |
|
||||
| 🚀 | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 |
|
||||
| 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 |
|
||||
| | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 |
|
||||
| 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、云片等主流短信平台 |
|
||||
| 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 |
|
||||
@ -87,6 +102,11 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
||||
* 2022 Q2 => 完成对 <https://github.com/YunaiV/onemall> 的迁移,作为 onemall 的 Spring Boot 单体版本。
|
||||
* 2022 Q4 => 完成对 <https://github.com/YunaiV/onemall>> 的重构,作为 onemall 的 Spring Cloud 微服务版本。
|
||||
|
||||
### 会员中心
|
||||
|
||||
正在开发中,大体计划如下:
|
||||
* 2021 Q1 =》完成对 <https://github.com/YunaiV/onemall> 的迁移
|
||||
|
||||
### 基础设施
|
||||
|
||||
| | 功能 | 描述 |
|
||||
@ -116,61 +136,64 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
||||
| 🚀 | 数据库文档 | 基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式 |
|
||||
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 |
|
||||
|
||||
## 技术栈
|
||||
## 🐨 技术栈
|
||||
|
||||
| 项目 | 说明 |
|
||||
| --- | --- |
|
||||
| `yudao-dependencies` | Maven 依赖版本管理 |
|
||||
| `yudao-framework` | Java 框架拓展 |
|
||||
| `yudao-admin-server` | 管理后台的服务端 |
|
||||
| `yudao-admin-ui` | 管理后台的 UI 界面 |
|
||||
| `yudao-user-server` | 用户前台的服务端 |
|
||||
| `yudao-user-ui` | 用户前台的 UI 界面 |
|
||||
| `yudao-core-service` | 公共服务,提供共享逻辑 |
|
||||
|
||||
> 友情提示:`yudao-admin-server` 和 `yudao-user-server` 会存在需要复用的逻辑,通过 `yudao-core-service` 实现。
|
||||
| 项目 | 说明 |
|
||||
|-----------------------|--------------------|
|
||||
| `yudao-dependencies` | Maven 依赖版本管理 |
|
||||
| `yudao-framework` | Java 框架拓展 |
|
||||
| `yudao-server` | 管理后台 + 用户 APP 的服务端 |
|
||||
| `yudao-admin-ui` | 管理后台的 UI 界面 |
|
||||
| `yudao-user-ui` | 用户 APP 的 UI 界面 |
|
||||
| `yudao-module-system` | 系统功能的 Module 模块 |
|
||||
| `yudao-module-member` | 会员中心的 Module 模块 |
|
||||
| `yudao-module-infra` | 基础设施的 Module 模块 |
|
||||
| `yudao-module-tool` | 研发工具的 Module 模块 |
|
||||
| `yudao-module-bpm` | 工作流程的 Module 模块 |
|
||||
| `yudao-module-pay` | 支付系统的 Module 模块 |
|
||||
|
||||
### 后端
|
||||
|
||||
| 框架 | 说明 | 版本 | 学习指南 |
|
||||
| --- | --- | --- | --- |
|
||||
| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.4.12 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
|
||||
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | |
|
||||
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.8 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.4.3.4 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
|
||||
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 | |
|
||||
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.16.6 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
|
||||
| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.13 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
|
||||
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.4.9 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
|
||||
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.1.7 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
|
||||
| 框架 | 说明 | 版本 | 学习指南 |
|
||||
| --- | --- |----------| --- |
|
||||
| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.5.10 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
|
||||
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | |
|
||||
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.8 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
|
||||
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 | |
|
||||
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.16.8 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
|
||||
| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.16 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
|
||||
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.5.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
|
||||
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.2 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
|
||||
| [Activiti](https://github.com/Activiti/Activiti) | 工作流引擎 | 7.1.0.M6 | [文档](TODO) |
|
||||
| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
|
||||
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.2 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
|
||||
| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
|
||||
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
||||
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.4.2 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
||||
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.11.4 | |
|
||||
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
||||
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
|
||||
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.1 | - |
|
||||
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.6.28 | - |
|
||||
| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
|
||||
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.2 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
|
||||
| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
|
||||
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
||||
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.4.2 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
||||
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.12.6 | |
|
||||
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
||||
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
|
||||
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.2 | - |
|
||||
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.9.0 | - |
|
||||
|
||||
### 前端
|
||||
|
||||
| 框架 | 说明 | 版本 |
|
||||
| --- | --- | --- |
|
||||
| [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.6.12 |
|
||||
| [Vue Element Admin](https://ant.design/docs/react/introduce-cn) | 后台前端解决方案 | - |
|
||||
| [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - |
|
||||
|
||||
## 演示图
|
||||
## 🐷 演示图
|
||||
|
||||
### 系统功能
|
||||
|
||||
| 模块 | biu | biu | biu |
|
||||
| --- | --- | --- | --- |
|
||||
| 登录 & 首页 |  |  |  |
|
||||
| 用户 & 租户 |  |  |  |
|
||||
| 模块 | biu | biu | biu |
|
||||
| --- | --- |------------------------------------------------------------------| --- |
|
||||
| 登录 & 首页 |  |  |  |
|
||||
| 用户 |  |  | - |
|
||||
| 租户 & 套餐 |  |  | - |
|
||||
| 部门 & 岗位 |  |  | - |
|
||||
| 菜单 & 角色 |  |  | - |
|
||||
| 审计日志 |  |  | - |
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
{
|
||||
"local": {
|
||||
"baseUrl": "http://127.0.0.1:48080/api",
|
||||
"userServerUrl": "http://127.0.0.1:28080/api",
|
||||
"token": "test1"
|
||||
"baseUrl": "http://127.0.0.1:48080/admin-api",
|
||||
"token": "test1",
|
||||
"adminTenentId": "1",
|
||||
|
||||
"appApi": "http://127.0.0.1:48080/app-api",
|
||||
"appToken": "test1",
|
||||
"appTenentId": "1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
config.stopBubbling = true
|
||||
lombok.tostring.callsuper=true
|
||||
lombok.equalsandhashcode.callsuper=true
|
||||
lombok.tostring.callsuper=CALL
|
||||
lombok.equalsandhashcode.callsuper=CALL
|
||||
lombok.accessors.chain=true
|
||||
|
||||
40
pom.xml
40
pom.xml
@ -10,22 +10,32 @@
|
||||
<modules>
|
||||
<module>yudao-dependencies</module>
|
||||
<module>yudao-framework</module>
|
||||
<module>yudao-admin-server</module>
|
||||
<module>yudao-user-server</module>
|
||||
<module>yudao-core-service</module>
|
||||
<!-- Server 主项目 -->
|
||||
<module>yudao-server</module>
|
||||
<!-- 各种 module 拓展 -->
|
||||
<module>yudao-module-member</module>
|
||||
<module>yudao-module-bpm</module>
|
||||
<module>yudao-module-system</module>
|
||||
<module>yudao-module-infra</module>
|
||||
<module>yudao-module-tool</module>
|
||||
<module>yudao-module-pay</module>
|
||||
</modules>
|
||||
|
||||
<name>${artifactId}</name>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>芋道项目基础脚手架</description>
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<properties>
|
||||
<revision>1.3.0-snapshot</revision>
|
||||
<revision>1.6.0-snapshot</revision>
|
||||
<!-- Maven 相关 -->
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
|
||||
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
||||
<!-- 看看咋放到 bom 里 -->
|
||||
<lombok.version>1.18.20</lombok.version>
|
||||
<mapstruct.version>1.4.1.Final</mapstruct.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -51,6 +61,26 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
<!-- maven-compiler-plugin 插件,解决 Lombok + MapStruct 组合 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
1517
sql/bpm-flowable.sql
Normal file
1517
sql/bpm-flowable.sql
Normal file
File diff suppressed because one or more lines are too long
140
sql/quartz.sql
140
sql/quartz.sql
@ -11,7 +11,7 @@
|
||||
Target Server Version : 80026
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 30/10/2021 13:46:03
|
||||
Date: 05/02/2022 00:50:30
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@ -22,14 +22,14 @@ SET FOREIGN_KEY_CHECKS = 0;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`BLOB_DATA` blob,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_BLOB_TRIGGERS
|
||||
@ -42,11 +42,11 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
|
||||
CREATE TABLE `QRTZ_CALENDARS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`CALENDAR_NAME` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`CALENDAR_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`CALENDAR` blob NOT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_CALENDARS
|
||||
@ -59,21 +59,21 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_CRON_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`CRON_EXPRESSION` varchar(120) NOT NULL,
|
||||
`TIME_ZONE_ID` varchar(80) DEFAULT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`CRON_EXPRESSION` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TIME_ZONE_ID` varchar(80) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_CRON_TRIGGERS
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', '* * * * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', '0 * * * * ? *', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', '0 * * * * ? *', 'Asia/Shanghai');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -81,19 +81,19 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`ENTRY_ID` varchar(95) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`INSTANCE_NAME` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`ENTRY_ID` varchar(95) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`INSTANCE_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`FIRED_TIME` bigint NOT NULL,
|
||||
`SCHED_TIME` bigint NOT NULL,
|
||||
`PRIORITY` int NOT NULL,
|
||||
`STATE` varchar(16) NOT NULL,
|
||||
`JOB_NAME` varchar(190) DEFAULT NULL,
|
||||
`JOB_GROUP` varchar(190) DEFAULT NULL,
|
||||
`IS_NONCONCURRENT` varchar(1) DEFAULT NULL,
|
||||
`REQUESTS_RECOVERY` varchar(1) DEFAULT NULL,
|
||||
`STATE` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`IS_NONCONCURRENT` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`REQUESTS_RECOVERY` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),
|
||||
KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),
|
||||
KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),
|
||||
@ -101,7 +101,7 @@ CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
|
||||
KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),
|
||||
KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_FIRED_TRIGGERS
|
||||
@ -114,27 +114,27 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
|
||||
CREATE TABLE `QRTZ_JOB_DETAILS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`JOB_NAME` varchar(190) NOT NULL,
|
||||
`JOB_GROUP` varchar(190) NOT NULL,
|
||||
`DESCRIPTION` varchar(250) DEFAULT NULL,
|
||||
`JOB_CLASS_NAME` varchar(250) NOT NULL,
|
||||
`IS_DURABLE` varchar(1) NOT NULL,
|
||||
`IS_NONCONCURRENT` varchar(1) NOT NULL,
|
||||
`IS_UPDATE_DATA` varchar(1) NOT NULL,
|
||||
`REQUESTS_RECOVERY` varchar(1) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`DESCRIPTION` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`JOB_CLASS_NAME` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`IS_DURABLE` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`IS_NONCONCURRENT` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`IS_UPDATE_DATA` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`REQUESTS_RECOVERY` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_DATA` blob,
|
||||
PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
|
||||
KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),
|
||||
KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_JOB_DETAILS
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000057400104A4F425F48414E444C45525F4E414D4574000C7061794E6F746966794A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000037400104A4F425F48414E444C45525F4E414D457400187379735573657253657373696F6E54696D656F75744A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000000000000000D7400104A4F425F48414E444C45525F4E414D457400157573657253657373696F6E54696D656F75744A6F627800);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -142,10 +142,10 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_LOCKS`;
|
||||
CREATE TABLE `QRTZ_LOCKS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`LOCK_NAME` varchar(40) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`LOCK_NAME` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_LOCKS
|
||||
@ -160,10 +160,10 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
|
||||
CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_PAUSED_TRIGGER_GRPS
|
||||
@ -176,12 +176,12 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
|
||||
CREATE TABLE `QRTZ_SCHEDULER_STATE` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`INSTANCE_NAME` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`INSTANCE_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`LAST_CHECKIN_TIME` bigint NOT NULL,
|
||||
`CHECKIN_INTERVAL` bigint NOT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_SCHEDULER_STATE
|
||||
@ -195,15 +195,15 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`REPEAT_COUNT` bigint NOT NULL,
|
||||
`REPEAT_INTERVAL` bigint NOT NULL,
|
||||
`TIMES_TRIGGERED` bigint NOT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_SIMPLE_TRIGGERS
|
||||
@ -216,23 +216,23 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`STR_PROP_1` varchar(512) DEFAULT NULL,
|
||||
`STR_PROP_2` varchar(512) DEFAULT NULL,
|
||||
`STR_PROP_3` varchar(512) DEFAULT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`STR_PROP_1` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`STR_PROP_2` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`STR_PROP_3` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`INT_PROP_1` int DEFAULT NULL,
|
||||
`INT_PROP_2` int DEFAULT NULL,
|
||||
`LONG_PROP_1` bigint DEFAULT NULL,
|
||||
`LONG_PROP_2` bigint DEFAULT NULL,
|
||||
`DEC_PROP_1` decimal(13,4) DEFAULT NULL,
|
||||
`DEC_PROP_2` decimal(13,4) DEFAULT NULL,
|
||||
`BOOL_PROP_1` varchar(1) DEFAULT NULL,
|
||||
`BOOL_PROP_2` varchar(1) DEFAULT NULL,
|
||||
`BOOL_PROP_1` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`BOOL_PROP_2` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_SIMPROP_TRIGGERS
|
||||
@ -245,20 +245,20 @@ COMMIT;
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
|
||||
CREATE TABLE `QRTZ_TRIGGERS` (
|
||||
`SCHED_NAME` varchar(120) NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) NOT NULL,
|
||||
`JOB_NAME` varchar(190) NOT NULL,
|
||||
`JOB_GROUP` varchar(190) NOT NULL,
|
||||
`DESCRIPTION` varchar(250) DEFAULT NULL,
|
||||
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`DESCRIPTION` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`NEXT_FIRE_TIME` bigint DEFAULT NULL,
|
||||
`PREV_FIRE_TIME` bigint DEFAULT NULL,
|
||||
`PRIORITY` int DEFAULT NULL,
|
||||
`TRIGGER_STATE` varchar(16) NOT NULL,
|
||||
`TRIGGER_TYPE` varchar(8) NOT NULL,
|
||||
`TRIGGER_STATE` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`TRIGGER_TYPE` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`START_TIME` bigint NOT NULL,
|
||||
`END_TIME` bigint DEFAULT NULL,
|
||||
`CALENDAR_NAME` varchar(190) DEFAULT NULL,
|
||||
`CALENDAR_NAME` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`MISFIRE_INSTR` smallint DEFAULT NULL,
|
||||
`JOB_DATA` blob,
|
||||
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
|
||||
@ -275,14 +275,14 @@ CREATE TABLE `QRTZ_TRIGGERS` (
|
||||
KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),
|
||||
KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
|
||||
CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of QRTZ_TRIGGERS
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `QRTZ_TRIGGERS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', 'payNotifyJob', 'DEFAULT', NULL, 1635572540000, 1635572539000, 5, 'WAITING', 'CRON', 1635294882000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 1635572580000, 1635572520000, 5, 'WAITING', 'CRON', 1613649236000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000007D074000F4A4F425F52455452595F434F554E547371007E0009000000037800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', 'userSessionTimeoutJob', 'DEFAULT', NULL, 1643993400000, -1, 5, 'WAITING', 'CRON', 1643993386000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000007D074000F4A4F425F52455452595F434F554E547371007E0009000000037800);
|
||||
COMMIT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,168 +0,0 @@
|
||||
<?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>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yudao-admin-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>yudao-admin-server</name>
|
||||
<description>管理后台 Server,提供其 API 接口</description>
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<dependencies>
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-core-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-sms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-activiti</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- spring boot 配置所需依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Config 配置中心相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息队列相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 服务保障相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-protection</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.codecentric</groupId>
|
||||
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.smallbun.screw</groupId>
|
||||
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
|
||||
</dependency>
|
||||
|
||||
<!-- 三方云服务相关 -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -1,14 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package} 和 ${yudao.core-service.base-package}
|
||||
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}", "${yudao.core-service.base-package}"})
|
||||
public class AdminServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AdminServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 使用 Spring Boot Admin 实现简单的监控平台
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.framework.monitor;
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* 属于整个 yudao-admin-server 的 framework 封装
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.framework;
|
||||
@ -1,41 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.framework.security;
|
||||
|
||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Resource
|
||||
private WebProperties webProperties;
|
||||
|
||||
@Value("${spring.boot.admin.context-path:''}")
|
||||
private String adminSeverContextPath;
|
||||
|
||||
@Bean
|
||||
public Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() {
|
||||
return registry -> {
|
||||
// 验证码的接口
|
||||
registry.antMatchers(api("/system/captcha/**")).anonymous();
|
||||
// 获得租户编号的接口
|
||||
registry.antMatchers(api("/system/tenant/get-id-by-name")).anonymous();
|
||||
// Spring Boot Admin Server 的安全配置
|
||||
registry.antMatchers(adminSeverContextPath).anonymous()
|
||||
.antMatchers(adminSeverContextPath + "/**").anonymous();
|
||||
// 短信回调 API
|
||||
registry.antMatchers(api("/system/sms/callback/**")).anonymous();
|
||||
};
|
||||
}
|
||||
|
||||
private String api(String url) {
|
||||
return webProperties.getApiPrefix() + url;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.io.IoUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "流程模型")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/model")
|
||||
@Validated
|
||||
public class BpmModelController {
|
||||
|
||||
@Resource
|
||||
private BpmModelService bpmModelService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation(value = "获得模型分页")
|
||||
public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(ModelPageReqVO pageVO) {
|
||||
return success(bpmModelService.getModelPage(pageVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得模型")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:query')")
|
||||
public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {
|
||||
BpmModelRespVO model = bpmModelService.getModel(id);
|
||||
return success(model);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation(value = "新建模型")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:create')")
|
||||
public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) {
|
||||
return success(bpmModelService.createModel(createRetVO, null));
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@ApiOperation(value = "导入模型")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:import')")
|
||||
public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
|
||||
BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
|
||||
// 读取文件
|
||||
String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);
|
||||
return success(bpmModelService.createModel(createReqVO, bpmnXml));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation(value = "修改模型")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:update')")
|
||||
public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) {
|
||||
bpmModelService.updateModel(modelVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除模型")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:delete')")
|
||||
public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {
|
||||
bpmModelService.deleteModel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/deploy")
|
||||
@ApiOperation(value = "部署模型")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:deploy')")
|
||||
public CommonResult<Boolean> deployModel(@RequestParam("id") String id) {
|
||||
bpmModelService.deployModel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-state")
|
||||
@ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:update')")
|
||||
public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {
|
||||
bpmModelService.updateModelState(reqVO.getId(), reqVO.getState());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "流程定义")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-definition")
|
||||
@Validated
|
||||
public class BpmProcessDefinitionController {
|
||||
|
||||
@Resource
|
||||
private BpmProcessDefinitionService bpmDefinitionService;
|
||||
|
||||
@GetMapping ("/page")
|
||||
@ApiOperation(value = "获得流程定义分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
|
||||
public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
|
||||
BpmProcessDefinitionPageReqVO pageReqVO) {
|
||||
return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
|
||||
}
|
||||
|
||||
@GetMapping ("/list")
|
||||
@ApiOperation(value = "获得流程定义列表")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
|
||||
public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(
|
||||
BpmProcessDefinitionListReqVO listReqVO) {
|
||||
return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));
|
||||
}
|
||||
|
||||
@GetMapping ("/get-bpmn-xml")
|
||||
@ApiOperation(value = "获得流程定义的 BPMN XML")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
|
||||
public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
|
||||
String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
|
||||
return success(bpmnXML);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "任务分配规则")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/task-assign-rule")
|
||||
@Validated
|
||||
public class BpmTaskAssignRuleController {
|
||||
|
||||
@Resource
|
||||
private BpmTaskAssignRuleService taskAssignRuleService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "获得任务分配规则列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class),
|
||||
@ApiImplicitParam(name = "processDefinitionId", value = "刘晨定义的编号", example = "2048", dataTypeClass = String.class)
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
|
||||
public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
|
||||
@RequestParam(value = "modelId", required = false) String modelId,
|
||||
@RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
|
||||
return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation(value = "创建任务分配规则")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")
|
||||
public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
|
||||
return success(taskAssignRuleService.createTaskAssignRule(reqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation(value = "更新任务分配规则")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")
|
||||
public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
|
||||
taskAssignRuleService.updateTaskAssignRule(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel("流程表单精简 Response VO")
|
||||
@Data
|
||||
public class BpmFormSimpleRespVO {
|
||||
|
||||
@ApiModelProperty(value = "表单编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "表单名称", required = true, example = "芋道")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("用户组创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupCreateReqVO extends BpmUserGroupBaseVO {
|
||||
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("用户组分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "组名", example = "芋道")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("用户组更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1024")
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(value = "流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmModeImportReqVO extends BpmModelCreateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "BPMN 文件", required = true)
|
||||
@NotNull(message = "BPMN 文件不能为空")
|
||||
private MultipartFile bpmnFile;
|
||||
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
|
||||
@ApiModel("流程模型分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ModelPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty(value = "名字", example = "芋道", notes = "模糊匹配")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
|
||||
private String category;
|
||||
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "流程活动实例")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/activity")
|
||||
@Validated
|
||||
public class BpmActivityController {
|
||||
|
||||
@Resource
|
||||
private BpmActivityService activityService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "生成指定流程实例的高亮流程图",
|
||||
notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
|
||||
@ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||
public CommonResult<List<BpmActivityRespVO>> getActivityList(
|
||||
@RequestParam("processInstanceId") String processInstanceId) {
|
||||
return success(activityService.getActivityListByProcessInstanceId(processInstanceId));
|
||||
}
|
||||
|
||||
@GetMapping("/generate-highlight-diagram")
|
||||
@ApiOperation(value = "生成指定流程实例的高亮流程图",
|
||||
notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
|
||||
@ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||
public void generateHighlightDiagram(@RequestParam("processInstanceId") String processInstanceId,
|
||||
HttpServletResponse response) throws IOException {
|
||||
byte[] bytes = activityService.generateHighlightDiagram(processInstanceId);
|
||||
ServletUtils.writeAttachment(response, StrUtil.format("流程图-{}.svg", processInstanceId), bytes);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Api(tags = "流程实例") // 流程实例,通过流程定义创建的一次“申请”
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-instance")
|
||||
@Validated
|
||||
public class BpmProcessInstanceController {
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("新建流程实例")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
||||
public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
|
||||
return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
@DeleteMapping("/cancel")
|
||||
@ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
|
||||
public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
|
||||
processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/my-page")
|
||||
@ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
||||
public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
|
||||
@Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
|
||||
return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")
|
||||
@ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
||||
public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
|
||||
return success(processInstanceService.getProcessInstanceVO(id));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Api(tags = "流程任务实例")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/task")
|
||||
@Validated
|
||||
public class BpmTaskController {
|
||||
|
||||
@Resource
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@GetMapping("todo-page")
|
||||
@ApiOperation("获取 Todo 待办任务分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||
public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {
|
||||
return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));
|
||||
}
|
||||
|
||||
@GetMapping("done-page")
|
||||
@ApiOperation("获取 Done 已办任务分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||
public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getTodoTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {
|
||||
return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
|
||||
}
|
||||
|
||||
@PutMapping("/approve")
|
||||
@ApiOperation("通过任务")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||
public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {
|
||||
taskService.approveTask(getLoginUserId(), reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/reject")
|
||||
@ApiOperation("不通过任务")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||
public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) {
|
||||
taskService.rejectTask(getLoginUserId(), reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-assignee")
|
||||
@ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||
public CommonResult<Boolean> updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) {
|
||||
taskService.updateTaskAssignee(getLoginUserId(), reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-process-instance-id")
|
||||
@ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
|
||||
@ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||
public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
|
||||
@RequestParam("processInstanceId") String processInstanceId) {
|
||||
return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormSimpleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 动态表单 Convert
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmFormConvert {
|
||||
|
||||
BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class);
|
||||
|
||||
BpmFormDO convert(BpmFormCreateReqVO bean);
|
||||
|
||||
BpmFormDO convert(BpmFormUpdateReqVO bean);
|
||||
|
||||
BpmFormRespVO convert(BpmFormDO bean);
|
||||
|
||||
List<BpmFormSimpleRespVO> convertList2(List<BpmFormDO> list);
|
||||
|
||||
PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page);
|
||||
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 流程模型 Convert
|
||||
*
|
||||
* @author yunlongn
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmModelConvert {
|
||||
|
||||
BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
|
||||
|
||||
default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
|
||||
Map<String, Deployment> deploymentMap,
|
||||
Map<String, ProcessDefinition> processDefinitionMap) {
|
||||
return CollectionUtils.convertList(list, model -> {
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
|
||||
Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
|
||||
ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
|
||||
return convert(model, form, deployment, processDefinition);
|
||||
});
|
||||
}
|
||||
|
||||
default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
|
||||
BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
|
||||
modelRespVO.setId(model.getId());
|
||||
modelRespVO.setCreateTime(model.getCreateTime());
|
||||
// 通用 copy
|
||||
copyTo(model, modelRespVO);
|
||||
// Form
|
||||
if (form != null) {
|
||||
modelRespVO.setFormId(form.getId());
|
||||
modelRespVO.setFormName(form.getName());
|
||||
}
|
||||
// ProcessDefinition
|
||||
modelRespVO.setProcessDefinition(this.convert(processDefinition));
|
||||
if (modelRespVO.getProcessDefinition() != null) {
|
||||
modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
|
||||
SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
|
||||
modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime());
|
||||
}
|
||||
return modelRespVO;
|
||||
}
|
||||
|
||||
default BpmModelRespVO convert(Model model) {
|
||||
BpmModelRespVO modelRespVO = new BpmModelRespVO();
|
||||
modelRespVO.setId(model.getId());
|
||||
modelRespVO.setCreateTime(model.getCreateTime());
|
||||
// 通用 copy
|
||||
copyTo(model, modelRespVO);
|
||||
return modelRespVO;
|
||||
}
|
||||
|
||||
default void copyTo(Model model, BpmModelBaseVO to) {
|
||||
to.setName(model.getName());
|
||||
to.setKey(model.getKey());
|
||||
to.setCategory(model.getCategory());
|
||||
// metaInfo
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
copyTo(metaInfo, to);
|
||||
}
|
||||
|
||||
void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);
|
||||
|
||||
default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) {
|
||||
BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO();
|
||||
createReqDTO.setModelId(model.getId());
|
||||
createReqDTO.setName(model.getName());
|
||||
createReqDTO.setKey(model.getKey());
|
||||
createReqDTO.setCategory(model.getCategory());
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
// metaInfo
|
||||
copyTo(metaInfo, createReqDTO);
|
||||
// form
|
||||
if (form != null) {
|
||||
createReqDTO.setFormConf(form.getConf());
|
||||
createReqDTO.setFormFields(form.getFields());
|
||||
}
|
||||
return createReqDTO;
|
||||
}
|
||||
|
||||
void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to);
|
||||
|
||||
default void copy(Model model, BpmModelCreateReqVO bean) {
|
||||
model.setName(bean.getName());
|
||||
model.setKey(bean.getKey());
|
||||
model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,
|
||||
null, null));
|
||||
}
|
||||
|
||||
default void copy(Model model, BpmModelUpdateReqVO bean) {
|
||||
model.setName(bean.getName());
|
||||
model.setCategory(bean.getCategory());
|
||||
model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),
|
||||
bean.getDescription(), bean.getFormType(), bean.getFormId(),
|
||||
bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));
|
||||
}
|
||||
|
||||
default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType,
|
||||
Long formId, String formCustomCreatePath, String formCustomViewPath) {
|
||||
if (metaInfo == null) {
|
||||
metaInfo = new BpmModelMetaInfoRespDTO();
|
||||
}
|
||||
// 只有非空,才进行设置,避免更新时的覆盖
|
||||
if (StrUtil.isNotEmpty(description)) {
|
||||
metaInfo.setDescription(description);
|
||||
}
|
||||
if (Objects.nonNull(formType)) {
|
||||
metaInfo.setFormType(formType);
|
||||
metaInfo.setFormId(formId);
|
||||
metaInfo.setFormCustomCreatePath(formCustomCreatePath);
|
||||
metaInfo.setFormCustomViewPath(formCustomViewPath);
|
||||
}
|
||||
return JsonUtils.toJsonString(metaInfo);
|
||||
}
|
||||
|
||||
BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
|
||||
|
||||
BpmModelCreateReqVO convert(BpmModeImportReqVO bean);
|
||||
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Bpm 流程定义的 Convert
|
||||
*
|
||||
* @author yunlong.li
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmProcessDefinitionConvert {
|
||||
|
||||
BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
|
||||
|
||||
default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
|
||||
return CollectionUtils.convertList(list, definition -> {
|
||||
Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
|
||||
BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
|
||||
BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
|
||||
return convert(definition, deployment, definitionDO, form);
|
||||
});
|
||||
}
|
||||
|
||||
default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
|
||||
BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
|
||||
BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
|
||||
respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
|
||||
if (deployment != null) {
|
||||
respVO.setDeploymentTime(deployment.getDeploymentTime());
|
||||
}
|
||||
if (form != null) {
|
||||
respVO.setFormName(form.getName());
|
||||
}
|
||||
// 复制通用属性
|
||||
copyTo(processDefinitionExtDO, respVO);
|
||||
return respVO;
|
||||
}
|
||||
|
||||
BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
|
||||
|
||||
BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);
|
||||
|
||||
default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
|
||||
return CollectionUtils.convertList(list, processDefinition -> {
|
||||
BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
|
||||
BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
|
||||
// 复制通用属性
|
||||
copyTo(processDefinitionExtDO, respVO);
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
@Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
|
||||
BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
|
||||
|
||||
@Named("convertSuspendedToSuspensionState")
|
||||
default Integer convertSuspendedToSuspensionState(boolean suspended) {
|
||||
return suspended ? SuspensionState.SUSPENDED.getStateCode() :
|
||||
SuspensionState.ACTIVE.getStateCode();
|
||||
}
|
||||
|
||||
@Mapping(source = "from.id", target = "to.id", ignore = true)
|
||||
void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);
|
||||
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Mapper
|
||||
public interface BpmTaskAssignRuleConvert {
|
||||
|
||||
BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
|
||||
|
||||
default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
|
||||
Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
|
||||
// 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
|
||||
return CollectionUtils.convertList(tasks, task -> {
|
||||
BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
|
||||
if (respVO == null) {
|
||||
respVO = new BpmTaskAssignRuleRespVO();
|
||||
respVO.setTaskDefinitionKey(task.getId());
|
||||
}
|
||||
respVO.setTaskDefinitionName(task.getName());
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
|
||||
|
||||
BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);
|
||||
|
||||
BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
|
||||
|
||||
List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
|
||||
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 用户组 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmUserGroupConvert {
|
||||
|
||||
BpmUserGroupConvert INSTANCE = Mappers.getMapper(BpmUserGroupConvert.class);
|
||||
|
||||
BpmUserGroupDO convert(BpmUserGroupCreateReqVO bean);
|
||||
|
||||
BpmUserGroupDO convert(BpmUserGroupUpdateReqVO bean);
|
||||
|
||||
BpmUserGroupRespVO convert(BpmUserGroupDO bean);
|
||||
|
||||
List<BpmUserGroupRespVO> convertList(List<BpmUserGroupDO> list);
|
||||
|
||||
PageResult<BpmUserGroupRespVO> convertPage(PageResult<BpmUserGroupDO> page);
|
||||
|
||||
@Named("convertList2")
|
||||
List<BpmUserGroupRespVO> convertList2(List<BpmUserGroupDO> list);
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.message;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import org.activiti.api.task.model.Task;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface BpmMessageConvert {
|
||||
|
||||
BpmMessageConvert INSTANCE = Mappers.getMapper(BpmMessageConvert.class);
|
||||
|
||||
default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, SysUserDO startUser, Task task) {
|
||||
BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
|
||||
copyTo(processInstance, reqDTO);
|
||||
copyTo(startUser, reqDTO);
|
||||
copyTo(task, reqDTO);
|
||||
return reqDTO;
|
||||
}
|
||||
@Mapping(source = "name", target = "processInstanceName")
|
||||
void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "startUserId"),
|
||||
@Mapping(source = "nickname", target = "startUserNickname")
|
||||
})
|
||||
void copyTo(SysUserDO from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "taskId"),
|
||||
@Mapping(source = "name", target = "taskName"),
|
||||
@Mapping(source = "assignee", target = "assigneeUserId")
|
||||
})
|
||||
void copyTo(Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
|
||||
|
||||
default BpmMessageSendWhenProcessInstanceRejectReqDTO convert(ProcessInstance processInstance, String comment) {
|
||||
BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO();
|
||||
copyTo(processInstance, reqDTO);
|
||||
reqDTO.setComment(comment);
|
||||
return reqDTO;
|
||||
}
|
||||
@Mapping(source = "name", target = "processInstanceName")
|
||||
void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenProcessInstanceRejectReqDTO to);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "processInstanceId"),
|
||||
@Mapping(source = "name", target = "processInstanceName"),
|
||||
@Mapping(source = "initiator", target = "startUserId")
|
||||
})
|
||||
BpmMessageSendWhenProcessInstanceApproveReqDTO convert(org.activiti.api.process.model.ProcessInstance processInstance);
|
||||
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.oa;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.BpmOALeaveCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.BpmOALeaveRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.BpmOALeaveDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 请假申请 Convert
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmOALeaveConvert {
|
||||
|
||||
BpmOALeaveConvert INSTANCE = Mappers.getMapper(BpmOALeaveConvert.class);
|
||||
|
||||
BpmOALeaveDO convert(BpmOALeaveCreateReqVO bean);
|
||||
|
||||
BpmOALeaveRespVO convert(BpmOALeaveDO bean);
|
||||
|
||||
List<BpmOALeaveRespVO> convertList(List<BpmOALeaveDO> list);
|
||||
|
||||
PageResult<BpmOALeaveRespVO> convertPage(PageResult<BpmOALeaveDO> page);
|
||||
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* 提供 POJO 类的实体转换
|
||||
*
|
||||
* 目前使用 MapStruct 框架
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert;
|
||||
@ -1,33 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.history.HistoricActivityInstance;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* BPM 活动 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmActivityConvert {
|
||||
|
||||
BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
|
||||
|
||||
List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "activityId", target = "key"),
|
||||
@Mapping(source = "activityType", target = "type")
|
||||
})
|
||||
BpmActivityRespVO convert(HistoricActivityInstance bean);
|
||||
|
||||
}
|
||||
@ -1,120 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEvent;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.sql.SQLXML;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 流程实例 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmProcessInstanceConvert {
|
||||
|
||||
BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
|
||||
|
||||
default BpmProcessInstanceExtDO convert3(ProcessInstance instance, ProcessDefinition definition) {
|
||||
BpmProcessInstanceExtDO ext = new BpmProcessInstanceExtDO();
|
||||
copyTo(instance, ext);
|
||||
copyTo(definition, ext);
|
||||
return ext;
|
||||
}
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "from.id", target = "id", ignore = true),
|
||||
@Mapping(source = "from.startTime", target = "createTime"),
|
||||
})
|
||||
void copyTo(ProcessInstance from, @MappingTarget BpmProcessInstanceExtDO to);
|
||||
@Mapping(source = "from.id", target = "id", ignore = true)
|
||||
void copyTo(ProcessDefinition from, @MappingTarget BpmProcessInstanceExtDO to);
|
||||
|
||||
default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page,
|
||||
Map<String, List<Task>> taskMap) {
|
||||
List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList());
|
||||
list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId()))));
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list);
|
||||
|
||||
List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks);
|
||||
|
||||
@Mapping(source = "processInstanceId", target = "id")
|
||||
BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "processInstanceId"),
|
||||
@Mapping(source = "id", target = "id", ignore = true),
|
||||
@Mapping(source = "startDate", target = "createTime"),
|
||||
@Mapping(source = "initiator", target = "startUserId"),
|
||||
@Mapping(source = "status", target = "status", ignore = true)
|
||||
})
|
||||
BpmProcessInstanceExtDO convert(org.activiti.api.process.model.ProcessInstance bean);
|
||||
|
||||
default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt,
|
||||
ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,
|
||||
String bpmnXml, SysUserDO startUser, SysDeptDO dept) {
|
||||
BpmProcessInstanceRespVO respVO = convert2(processInstance);
|
||||
copyTo(processInstanceExt, respVO);
|
||||
// definition
|
||||
respVO.setProcessDefinition(convert2(processDefinition));
|
||||
copyTo(processDefinitionExt, respVO.getProcessDefinition());
|
||||
respVO.getProcessDefinition().setBpmnXml(bpmnXml);
|
||||
// user
|
||||
if (startUser != null) {
|
||||
respVO.setStartUser(convert2(startUser));
|
||||
if (dept != null) {
|
||||
respVO.getStartUser().setDeptName(dept.getName());
|
||||
}
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
|
||||
BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);
|
||||
@Mapping(source = "from.id", target = "to.id", ignore = true)
|
||||
void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to);
|
||||
BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
|
||||
@Mapping(source = "from.id", target = "to.id", ignore = true)
|
||||
void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
|
||||
BpmProcessInstanceRespVO.User convert2(SysUserDO bean);
|
||||
|
||||
default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {
|
||||
BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
|
||||
event.setId(instance.getId());
|
||||
event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
|
||||
event.setBusinessKey(instance.getBusinessKey());
|
||||
event.setResult(result);
|
||||
return event;
|
||||
}
|
||||
|
||||
default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
|
||||
BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
|
||||
event.setId(instance.getId());
|
||||
event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
|
||||
event.setBusinessKey(instance.getBusinessKey());
|
||||
event.setResult(result);
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,126 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.history.HistoricTaskInstance;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.mapstruct.*;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Bpm 任务 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmTaskConvert {
|
||||
|
||||
BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
|
||||
|
||||
default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
|
||||
Map<Long, SysUserDO> userMap) {
|
||||
return CollectionUtils.convertList(tasks, task -> {
|
||||
BpmTaskTodoPageItemRespVO respVO = convert1(task);
|
||||
ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
|
||||
if (processInstance != null) {
|
||||
SysUserDO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
respVO.setProcessInstance(convert(processInstance, startUser));
|
||||
}
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
@Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
|
||||
BpmTaskTodoPageItemRespVO convert1(Task bean);
|
||||
|
||||
@Named("convertSuspendedToSuspensionState")
|
||||
default Integer convertSuspendedToSuspensionState(boolean suspended) {
|
||||
return suspended ? SuspensionState.SUSPENDED.getStateCode() :
|
||||
SuspensionState.ACTIVE.getStateCode();
|
||||
}
|
||||
|
||||
default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
|
||||
Map<String, HistoricProcessInstance> historicProcessInstanceMap,
|
||||
Map<Long, SysUserDO> userMap) {
|
||||
return CollectionUtils.convertList(tasks, task -> {
|
||||
BpmTaskDonePageItemRespVO respVO = convert2(task);
|
||||
BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
|
||||
copyTo(taskExtDO, respVO);
|
||||
HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId());
|
||||
if (processInstance != null) {
|
||||
SysUserDO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
respVO.setProcessInstance(convert(processInstance, startUser));
|
||||
}
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "taskId"),
|
||||
@Mapping(source = "assignee", target = "assigneeUserId"),
|
||||
@Mapping(source = "createdDate", target = "createTime")
|
||||
})
|
||||
BpmTaskExtDO convert(org.activiti.api.task.model.Task bean);
|
||||
|
||||
default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
|
||||
HistoricProcessInstance processInstance, Map<Long, SysUserDO> userMap,
|
||||
Map<Long, SysDeptDO> deptMap) {
|
||||
return CollectionUtils.convertList(tasks, task -> {
|
||||
BpmTaskRespVO respVO = convert3(task);
|
||||
BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
|
||||
copyTo(taskExtDO, respVO);
|
||||
if (processInstance != null) {
|
||||
SysUserDO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
respVO.setProcessInstance(convert(processInstance, startUser));
|
||||
}
|
||||
SysUserDO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
|
||||
if (assignUser != null) {
|
||||
respVO.setAssigneeUser(convert3(assignUser));
|
||||
SysDeptDO dept = deptMap.get(assignUser.getDeptId());
|
||||
if (dept != null) {
|
||||
respVO.getAssigneeUser().setDeptName(dept.getName());
|
||||
}
|
||||
}
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
@Mapping(source = "taskDefinitionKey", target = "definitionKey")
|
||||
BpmTaskRespVO convert3(HistoricTaskInstance bean);
|
||||
BpmTaskRespVO.User convert3(SysUserDO bean);
|
||||
|
||||
void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "processInstance.id", target = "id"),
|
||||
@Mapping(source = "processInstance.name", target = "name"),
|
||||
@Mapping(source = "processInstance.startUserId", target = "startUserId"),
|
||||
@Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
|
||||
@Mapping(source = "startUser.nickname", target = "startUserNickname")
|
||||
})
|
||||
BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, SysUserDO startUser);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "processInstance.id", target = "id"),
|
||||
@Mapping(source = "processInstance.name", target = "name"),
|
||||
@Mapping(source = "processInstance.startUserId", target = "startUserId"),
|
||||
@Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
|
||||
@Mapping(source = "startUser.nickname", target = "startUserNickname")
|
||||
})
|
||||
BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, SysUserDO startUser);
|
||||
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
// TODO 芋艿:先埋个坑。任务消息的配置规则。说白了,就是不同的
|
||||
public class BpmTaskMessageRuleDO {
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Bpm 流程实例的拓展表
|
||||
* 主要解决 Activiti {@link ProcessInstance} 和 {@link HistoricProcessInstance} 不支持拓展字段,所以新建拓展表
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "bpm_process_instance_ext", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
//@Builder
|
||||
//@NoArgsConstructor
|
||||
//@AllArgsConstructor
|
||||
public class BpmProcessInstanceExtDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 发起流程的用户编号
|
||||
*
|
||||
* 冗余 {@link HistoricProcessInstance#getStartUserId()}
|
||||
*/
|
||||
private Long startUserId;
|
||||
/**
|
||||
* 流程实例的名字
|
||||
*
|
||||
* 冗余 {@link ProcessInstance#getName()} 为了筛选
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 流程实例的编号
|
||||
*
|
||||
* 关联 {@link ProcessInstance#getId()}
|
||||
*/
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程定义的编号
|
||||
*
|
||||
* 关联 {@link ProcessDefinition#getId()}
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程分类
|
||||
*
|
||||
* 冗余 {@link ProcessDefinition#getCategory()}
|
||||
* 数据字典 bpm_model_category
|
||||
*/
|
||||
private String category;
|
||||
/**
|
||||
* 流程实例的状态
|
||||
*
|
||||
* 枚举 {@link BpmProcessInstanceStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 流程实例的结果
|
||||
*
|
||||
* 枚举 {@link BpmProcessInstanceResultEnum}
|
||||
*/
|
||||
private Integer result;
|
||||
/**
|
||||
* 结束时间
|
||||
*
|
||||
* 冗余 {@link HistoricProcessInstance#getEndTime()}
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 提交的表单值
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.activiti.engine.history.HistoricTaskInstance;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Bpm 流程任务的拓展表
|
||||
* 主要解决 Activiti {@link Task} 和 {@link HistoricTaskInstance} 不支持拓展字段,所以新建拓展表
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "bpm_task_ext", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
//@Builder
|
||||
//@NoArgsConstructor
|
||||
//@AllArgsConstructor
|
||||
public class BpmTaskExtDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 任务的审批人
|
||||
*
|
||||
* 冗余 {@link Task#getAssignee()}
|
||||
*/
|
||||
private Long assigneeUserId;
|
||||
/**
|
||||
* 任务的名字
|
||||
*
|
||||
* 冗余 {@link Task#getName()} 为了筛选
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 任务的编号
|
||||
*
|
||||
* 关联 {@link Task#getId()}
|
||||
*/
|
||||
private String taskId;
|
||||
// /**
|
||||
// * 任务的标识
|
||||
// *
|
||||
// * 关联 {@link Task#getTaskDefinitionKey()}
|
||||
// */
|
||||
// private String definitionKey;
|
||||
/**
|
||||
* 任务的结果
|
||||
*
|
||||
* 枚举 {@link BpmProcessInstanceResultEnum}
|
||||
*/
|
||||
private Integer result;
|
||||
/**
|
||||
* 审批建议
|
||||
*/
|
||||
private String comment;
|
||||
/**
|
||||
* 任务的结束时间
|
||||
*
|
||||
* 冗余 {@link HistoricTaskInstance#getEndTime()}
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 流程实例的编号
|
||||
*
|
||||
* 关联 {@link ProcessInstance#getId()}
|
||||
*/
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程定义的编号
|
||||
*
|
||||
* 关联 {@link ProcessDefinition#getId()}
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 动态表单 Mapper
|
||||
*
|
||||
* @author 风里雾里
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
|
||||
|
||||
default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new QueryWrapperX<BpmFormDO>()
|
||||
.likeIfPresent("name", reqVO.getName())
|
||||
.orderByDesc("id"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
|
||||
|
||||
default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
|
||||
return selectList("process_definition_id", processDefinitionIds);
|
||||
}
|
||||
|
||||
default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
|
||||
return selectOne("process_definition_id", processDefinitionId);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* 工作流 错误码枚举类
|
||||
*
|
||||
* 工作流系统,使用 1-009-000-000 段
|
||||
*/
|
||||
public interface BpmErrorCodeConstants {
|
||||
|
||||
// ========== 通用流程处理 模块 1-009-000-000 ==========
|
||||
ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
|
||||
|
||||
// ========== OA 流程模块 1-009-001-000 ==========
|
||||
ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在");
|
||||
ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置");
|
||||
ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在");
|
||||
ErrorCode OA_BM_POST_NOT_EXISTS = new ErrorCode(1009001004, "部门经理岗位未设置");
|
||||
ErrorCode OA_DEPART_BM_POST_NOT_EXISTS = new ErrorCode(1009001005, "部门的部门经理不存在");
|
||||
ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置");
|
||||
ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1");
|
||||
|
||||
// ========== 流程模型 1-009-002-000 ==========
|
||||
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
|
||||
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
|
||||
ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," +
|
||||
"原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化");
|
||||
|
||||
// ========== 流程定义 1-009-003-000 ==========
|
||||
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
|
||||
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003003, "流程定义处于挂起状态");
|
||||
ErrorCode PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS = new ErrorCode(1009003004, "流程定义的模型不存在");
|
||||
|
||||
// ========== 流程实例 1-009-004-000 ==========
|
||||
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
|
||||
|
||||
// ========== 流程任务 1-009-005-000 ==========
|
||||
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批");
|
||||
ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009004001, "审批任务失败,原因:该任务的审批人不是你");
|
||||
|
||||
// ========== 流程任务分配规则 1-009-006-000 ==========
|
||||
ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则");
|
||||
ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在");
|
||||
ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改");
|
||||
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!");
|
||||
ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在");
|
||||
|
||||
// ========== 动态表单模块 1-009-010-000 ==========
|
||||
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
|
||||
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010000, "表单项({}) 和 ({}) 使用了相同的字段名({})");
|
||||
|
||||
// ========== 用户组模块 1-009-011-000 ==========
|
||||
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在");
|
||||
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用");
|
||||
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.enums.message;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Bpm 消息的枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum BpmMessageEnum {
|
||||
|
||||
PROCESS_INSTANCE_APPROVE("bpm_process_instance_approve"), // 流程任务被审批通过时,发送给申请人
|
||||
PROCESS_INSTANCE_REJECT("bpm_process_instance_reject"), // 流程任务被审批不通过时,发送给申请人
|
||||
TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时,发送给审批人
|
||||
|
||||
/**
|
||||
* 短信模板的标识
|
||||
*
|
||||
* 关联 {@link SysSmsTemplateDO#getCode()}
|
||||
*/
|
||||
private final String smsCode;
|
||||
|
||||
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventPublisher;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.identity.EmptyUserGroupManager;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import org.activiti.api.runtime.shared.identity.UserGroupManager;
|
||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.activiti.spring.boot.ProcessEngineAutoConfiguration.BEHAVIOR_FACTORY_MAPPING_CONFIGURER;
|
||||
|
||||
/**
|
||||
* BPM 模块的 Activiti 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class BpmActivitiConfiguration {
|
||||
|
||||
/**
|
||||
* BPM 模块的 ProcessEngineConfigurationConfigurer 实现类,主要设置各种监听器、用户组管理
|
||||
*/
|
||||
@Bean
|
||||
public ProcessEngineConfigurationConfigurer bpmProcessEngineConfigurationConfigurer(
|
||||
BpmTackActivitiEventListener taskActivitiEventListener) {
|
||||
return configuration -> {
|
||||
// 注册监听器,例如说 BpmActivitiEventListener
|
||||
configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener));
|
||||
// 用户组
|
||||
configuration.setUserGroupManager(new EmptyUserGroupManager());
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于设置自定义的 ActivityBehaviorFactory 实现的 ProcessEngineConfigurationConfigurer 实现类
|
||||
*
|
||||
* 目的:覆盖 {@link org.activiti.spring.boot.ProcessEngineAutoConfiguration} 的
|
||||
* defaultActivityBehaviorFactoryMappingConfigurer 方法创建的 Bean
|
||||
*/
|
||||
@Bean(name = BEHAVIOR_FACTORY_MAPPING_CONFIGURER)
|
||||
public ProcessEngineConfigurationConfigurer defaultActivityBehaviorFactoryMappingConfigurer(
|
||||
BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
|
||||
return configuration -> {
|
||||
// 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
|
||||
configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
|
||||
SysPermissionService permissionService,
|
||||
SysDeptService deptService,
|
||||
BpmUserGroupService userGroupService,
|
||||
SysUserService userService,
|
||||
List<BpmTaskAssignScript> scripts) {
|
||||
BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
|
||||
bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
|
||||
bpmActivityBehaviorFactory.setPermissionService(permissionService);
|
||||
bpmActivityBehaviorFactory.setDeptService(deptService);
|
||||
bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
|
||||
bpmActivityBehaviorFactory.setUserService(userService);
|
||||
bpmActivityBehaviorFactory.setScripts(scripts);
|
||||
return bpmActivityBehaviorFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) {
|
||||
return new BpmProcessInstanceResultEventPublisher(publisher);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义的 ActivityBehaviorFactory 实现类,目的如下:
|
||||
* 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
|
||||
|
||||
@Setter
|
||||
private BpmTaskAssignRuleService bpmTaskRuleService;
|
||||
@Setter
|
||||
private SysPermissionService permissionService;
|
||||
@Setter
|
||||
private SysDeptService deptService;
|
||||
@Setter
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Setter
|
||||
private SysUserService userService;
|
||||
@Setter
|
||||
private List<BpmTaskAssignScript> scripts;
|
||||
|
||||
@Override
|
||||
public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
|
||||
BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
|
||||
userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
|
||||
userTaskActivityBehavior.setPermissionService(permissionService);
|
||||
userTaskActivityBehavior.setDeptService(deptService);
|
||||
userTaskActivityBehavior.setUserGroupService(userGroupService);
|
||||
userTaskActivityBehavior.setUserService(userService);
|
||||
userTaskActivityBehavior.setScripts(scripts);
|
||||
return userTaskActivityBehavior;
|
||||
}
|
||||
|
||||
// TODO 芋艿:并行任务 ParallelMultiInstanceBehavior
|
||||
|
||||
// TODO 芋艿:并行任务 SequentialMultiInstanceBehavior
|
||||
|
||||
}
|
||||
@ -1,193 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.ActivitiException;
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
import org.activiti.engine.impl.el.ExpressionManager;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||
|
||||
/**
|
||||
* 自定义的流程任务的 assignee 负责人的分配
|
||||
* 第一步,获得对应的分配规则;
|
||||
* 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
|
||||
* 第三步,随机选择一个候选人,则选择作为 assignee 负责人。
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
|
||||
|
||||
@Setter
|
||||
private BpmTaskAssignRuleService bpmTaskRuleService;
|
||||
@Setter
|
||||
private SysPermissionService permissionService;
|
||||
@Setter
|
||||
private SysDeptService deptService;
|
||||
@Setter
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Setter
|
||||
private SysUserService userService;
|
||||
/**
|
||||
* 任务分配脚本
|
||||
*/
|
||||
private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
|
||||
|
||||
public BpmUserTaskActivitiBehavior(UserTask userTask) {
|
||||
super(userTask);
|
||||
}
|
||||
|
||||
public void setScripts(List<BpmTaskAssignScript> scripts) {
|
||||
this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleAssignments(TaskEntityManager taskEntityManager,
|
||||
String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups,
|
||||
TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {
|
||||
// 第一步,获得任务的规则
|
||||
BpmTaskAssignRuleDO rule = getTaskRule(task);
|
||||
// 第二步,获得任务的候选用户们
|
||||
Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);
|
||||
// 第三步,设置一个作为负责人
|
||||
Long assigneeUserId = chooseTaskAssignee(candidateUserIds);
|
||||
taskEntityManager.changeTaskAssignee(task, String.valueOf(assigneeUserId));
|
||||
}
|
||||
|
||||
private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) {
|
||||
List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(),
|
||||
task.getTaskDefinitionKey());
|
||||
if (CollUtil.isEmpty(taskRules)) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));
|
||||
}
|
||||
if (taskRules.size() > 1) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));
|
||||
}
|
||||
return taskRules.get(0);
|
||||
}
|
||||
|
||||
private Long chooseTaskAssignee(Set<Long> candidateUserIds) {
|
||||
// TODO 芋艿:未来可以优化下,改成轮询的策略
|
||||
int index = RandomUtil.randomInt(candidateUserIds.size());
|
||||
return CollUtil.get(candidateUserIds, index);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
Set<Long> assigneeUserIds = null;
|
||||
if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);
|
||||
}
|
||||
|
||||
// 移除被禁用的用户
|
||||
removeDisableUsers(assigneeUserIds);
|
||||
// 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));
|
||||
throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
|
||||
}
|
||||
return assigneeUserIds;
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
return permissionService.getUserRoleIdListByRoleIds(rule.getOptions());
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysUserDO> users = userService.getUsersByDeptIds(rule.getOptions());
|
||||
return convertSet(users, SysUserDO::getId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysDeptDO> depts = deptService.getDepts(rule.getOptions());
|
||||
return convertSet(depts, SysDeptDO::getLeaderUserId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysUserDO> users = userService.getUsersByPostIds(rule.getOptions());
|
||||
return convertSet(users, SysUserDO::getId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
return rule.getOptions();
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
|
||||
Set<Long> userIds = new HashSet<>();
|
||||
userGroups.forEach(bpmUserGroupDO -> userIds.addAll(bpmUserGroupDO.getMemberUserIds()));
|
||||
return userIds;
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
// 获得对应的脚本
|
||||
List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
|
||||
rule.getOptions().forEach(id -> {
|
||||
BpmTaskAssignScript script = scriptMap.get(id);
|
||||
if (script == null) {
|
||||
throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
|
||||
}
|
||||
scripts.add(script);
|
||||
});
|
||||
// 逐个计算任务
|
||||
Set<Long> userIds = new HashSet<>();
|
||||
scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task)));
|
||||
return userIds;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void removeDisableUsers(Set<Long> assigneeUserIds) {
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
return;
|
||||
}
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(assigneeUserIds);
|
||||
assigneeUserIds.removeIf(id -> {
|
||||
SysUserDO user = userMap.get(id);
|
||||
return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* 拓展 {@link org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior} 实现,基于 {@link cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO} 实现自定义的任务分配规则。
|
||||
* 原因:BPMN 默认的 assign、candidateUsers、candidateGroups 拓展起来有一定的难度,所以选择放弃它们,使用自己定义的规则。
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Bpm 任务分配的自定义 Script 脚本
|
||||
* 使用场景:
|
||||
* 1. 设置审批人为发起人
|
||||
* 2. 设置审批人为发起人的 Leader
|
||||
* 3. 甚至审批人为发起人的 Leader 的 Leader
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskAssignScript {
|
||||
|
||||
/**
|
||||
* 基于流程任务,获得任务的候选用户们
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 候选人用户的编号数组
|
||||
*/
|
||||
Set<Long> calculateTaskCandidateUsers(TaskEntity task);
|
||||
|
||||
/**
|
||||
* 获得枚举值
|
||||
*
|
||||
* @return 枚举值
|
||||
*/
|
||||
BpmTaskRuleScriptEnum getEnum();
|
||||
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static java.util.Collections.emptySet;
|
||||
|
||||
/**
|
||||
* 分配给发起人的 Leader 审批的 Script 实现类
|
||||
* 目前 Leader 的定义是,
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
|
||||
protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) {
|
||||
Assert.isTrue(level > 0, "level 必须大于 0");
|
||||
// 获得发起人
|
||||
Long startUserId = Long.parseLong(task.getProcessInstance().getStartUserId());
|
||||
// 获得对应 leve 的部门
|
||||
SysDeptDO dept = null;
|
||||
for (int i = 0; i < level; i++) {
|
||||
// 获得 level 对应的部门
|
||||
if (dept == null) {
|
||||
dept = getStartUserDept(startUserId);
|
||||
if (dept == null) { // 找不到发起人的部门,所以无法使用该规则
|
||||
return emptySet();
|
||||
}
|
||||
} else {
|
||||
SysDeptDO parentDept = deptService.getDept(dept.getParentId());
|
||||
if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少
|
||||
break;
|
||||
}
|
||||
dept = parentDept;
|
||||
}
|
||||
}
|
||||
return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();
|
||||
}
|
||||
|
||||
private SysDeptDO getStartUserDept(Long startUserId) {
|
||||
SysUserDO startUser = userService.getUser(startUserId);
|
||||
if (startUser.getDeptId() == null) { // 找不到部门,所以无法使用该规则
|
||||
return null;
|
||||
}
|
||||
return deptService.getDept(startUser.getDeptId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 分配给发起人的一级 Leader 审批的 Script 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
|
||||
return calculateTaskCandidateUsers(task, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmTaskRuleScriptEnum getEnum() {
|
||||
return BpmTaskRuleScriptEnum.LEADER_X1;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 分配给发起人的二级 Leader 审批的 Script 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
|
||||
return calculateTaskCandidateUsers(task, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmTaskRuleScriptEnum getEnum() {
|
||||
return BpmTaskRuleScriptEnum.LEADER_X2;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 分配给发起人审批的 Script 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
|
||||
Long userId = Long.parseLong(task.getProcessInstance().getStartUserId());
|
||||
return SetUtils.asSet(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmTaskRuleScriptEnum getEnum() {
|
||||
return BpmTaskRuleScriptEnum.START_USER;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* 自定义 Event 实现,提供方便业务接入的 Listener!
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event;
|
||||
@ -1,60 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import org.activiti.api.model.shared.event.RuntimeEvent;
|
||||
import org.activiti.api.process.model.ProcessInstance;
|
||||
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
|
||||
import org.activiti.api.process.runtime.events.ProcessCancelledEvent;
|
||||
import org.activiti.api.process.runtime.events.listener.ProcessEventListener;
|
||||
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
|
||||
import org.activiti.api.task.model.events.TaskRuntimeEvent;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmProcessInstanceEventListener<T extends RuntimeEvent<?, ?>>
|
||||
implements ProcessRuntimeEventListener<T> {
|
||||
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onEvent(T rawEvent) {
|
||||
// 由于 ProcessRuntimeEventListener 无法保证只监听 ProcessRuntimeEvent 事件,所以通过这样的方式
|
||||
if (!(rawEvent instanceof ProcessRuntimeEvent)) {
|
||||
return;
|
||||
}
|
||||
ProcessRuntimeEvent<ProcessInstance> event = (ProcessRuntimeEvent<ProcessInstance>) rawEvent;
|
||||
|
||||
// 创建时,插入拓展表
|
||||
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED) {
|
||||
processInstanceService.createProcessInstanceExt(event.getEntity());
|
||||
return;
|
||||
}
|
||||
// 取消时,更新拓展表为取消
|
||||
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CANCELLED) {
|
||||
processInstanceService.updateProcessInstanceExtCancel(event.getEntity(),
|
||||
((ProcessCancelledEvent) event).getCause());
|
||||
return;
|
||||
}
|
||||
// 完成时,更新拓展表为已完成
|
||||
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_COMPLETED) {
|
||||
processInstanceService.updateProcessInstanceExtComplete(event.getEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
// 其它事件,进行更新拓展表
|
||||
processInstanceService.updateProcessInstanceExt(event.getEntity());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import org.activiti.api.model.shared.event.RuntimeEvent;
|
||||
import org.activiti.api.process.model.ProcessInstance;
|
||||
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
|
||||
import org.activiti.api.task.model.Task;
|
||||
import org.activiti.api.task.model.events.TaskRuntimeEvent;
|
||||
import org.activiti.api.task.runtime.events.listener.TaskEventListener;
|
||||
import org.activiti.api.task.runtime.events.listener.TaskRuntimeEventListener;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 监听 {@link Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>
|
||||
implements TaskRuntimeEventListener<T> {
|
||||
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onEvent(T rawEvent) {
|
||||
// 由于 TaskRuntimeEventListener 无法保证只监听 TaskRuntimeEvent 事件,所以通过这样的方式
|
||||
if (!(rawEvent instanceof TaskRuntimeEvent)) {
|
||||
return;
|
||||
}
|
||||
TaskRuntimeEvent<Task> event = (TaskRuntimeEvent<Task>) rawEvent;
|
||||
|
||||
// 创建时,插入拓展表
|
||||
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CREATED) {
|
||||
taskService.createTaskExt(event.getEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
// 取消时,更新拓展表为取消
|
||||
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CANCELLED) {
|
||||
taskService.updateTaskExtCancel(event.getEntity());
|
||||
return;
|
||||
}
|
||||
// 完成时,更新拓展表为已完成。要注意,在调用 delete ProcessInstance 才会触发该逻辑
|
||||
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_COMPLETED) {
|
||||
taskService.updateTaskExtComplete(event.getEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
// 审核人修改时,进行拓展表,并额外发送通知
|
||||
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED) {
|
||||
taskService.updateTaskExtAssign(event.getEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
// 其它事件,进行更新拓展表
|
||||
taskService.updateTaskExt(event.getEntity());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* 自定义各种 Activiti 的监听器,实现流程示例、流程任务的拓展表信息的同步
|
||||
* 例如说,{@link org.activiti.api.task.model.Task} 新建时,我们也要新建对应的 {@link cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO} 记录
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* 属于 bpm 模块的 framework 封装
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework;
|
||||
@ -1,9 +0,0 @@
|
||||
/**
|
||||
* bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。
|
||||
* 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
|
||||
*
|
||||
* bpm 解释:https://baike.baidu.com/item/BPM/1933
|
||||
*
|
||||
* 缩写:bpm
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm;
|
||||
@ -1,78 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 流程模型接口
|
||||
*
|
||||
* @author yunlongn
|
||||
*/
|
||||
public interface BpmModelService {
|
||||
|
||||
/**
|
||||
* 获得流程模型分页
|
||||
*
|
||||
* @param pageVO 分页查询
|
||||
* @return 流程模型分页
|
||||
*/
|
||||
PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO);
|
||||
|
||||
/**
|
||||
* 获得流程模块
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程模型
|
||||
*/
|
||||
BpmModelRespVO getModel(String id);
|
||||
|
||||
/**
|
||||
* 创建流程模型
|
||||
*
|
||||
* @param modelVO 创建信息
|
||||
* @param bpmnXml BPMN XML
|
||||
* @return 创建的流程模型的编号
|
||||
*/
|
||||
String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml);
|
||||
|
||||
/**
|
||||
* 修改流程模型
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateModel(@Valid BpmModelUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 将流程模型,部署成一个流程定义
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deployModel(String id);
|
||||
|
||||
/**
|
||||
* 删除模型
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteModel(String id);
|
||||
|
||||
/**
|
||||
* 修改模型的状态,实际更新的部署的流程定义的状态
|
||||
*
|
||||
* @param id 编号
|
||||
* @param state 状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
|
||||
*/
|
||||
void updateModelState(String id, Integer state);
|
||||
|
||||
/**
|
||||
* 获得流程模型编号对应的 BPMN Model
|
||||
*
|
||||
* @param id 流程模型编号
|
||||
* @return BPMN Model
|
||||
*/
|
||||
BpmnModel getBpmnModel(String id);
|
||||
|
||||
}
|
||||
@ -1,161 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 流程定义接口
|
||||
*
|
||||
* @author yunlong.li
|
||||
* @author ZJQ
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmProcessDefinitionService {
|
||||
|
||||
/**
|
||||
* 获得流程定义分页
|
||||
*
|
||||
* @param pageReqVO 分页入参
|
||||
* @return 流程定义 Page
|
||||
*/
|
||||
PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得流程定义列表
|
||||
*
|
||||
* @param listReqVO 列表入参
|
||||
* @return 流程定义列表
|
||||
*/
|
||||
List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
|
||||
|
||||
/**
|
||||
* 获得流程定义对应的 BPMN XML
|
||||
*
|
||||
* @param id 流程定义编号
|
||||
* @return BPMN XML
|
||||
*/
|
||||
String getProcessDefinitionBpmnXML(String id);
|
||||
|
||||
/**
|
||||
* 获得 Bpmn 模型
|
||||
*
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @return Bpmn 模型
|
||||
*/
|
||||
BpmnModel getBpmnModel(String processDefinitionId);
|
||||
|
||||
/**
|
||||
* 获得编号对应的 ProcessDefinition
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程定义
|
||||
*/
|
||||
ProcessDefinition getProcessDefinition(String id);
|
||||
|
||||
/**
|
||||
* 获得编号对应的 ProcessDefinition
|
||||
*
|
||||
* 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程定义
|
||||
*/
|
||||
ProcessDefinition getProcessDefinition2(String id);
|
||||
|
||||
/**
|
||||
* 获得流程定义标识对应的激活的流程定义
|
||||
*
|
||||
* @param key 流程定义的标识
|
||||
* @return 流程定义
|
||||
*/
|
||||
ProcessDefinition getActiveProcessDefinition(String key);
|
||||
|
||||
/**
|
||||
* 获得编号对应的 BpmProcessDefinitionExtDO
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程定义拓展
|
||||
*/
|
||||
BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
|
||||
|
||||
/**
|
||||
* 获得 id 对应的 Deployment
|
||||
*
|
||||
* @param id 部署编号
|
||||
* @return 流程部署
|
||||
*/
|
||||
Deployment getDeployment(String id);
|
||||
|
||||
/**
|
||||
* 获得 ids 对应的 Deployment 数组
|
||||
*
|
||||
* @param ids 部署编号的数组
|
||||
* @return 流程部署的数组
|
||||
*/
|
||||
List<Deployment> getDeployments(Set<String> ids);
|
||||
|
||||
/**
|
||||
* 获得 ids 对应的 Deployment Map
|
||||
*
|
||||
* @param ids 部署编号的数组
|
||||
* @return 流程部署 Map
|
||||
*/
|
||||
default Map<String, Deployment> getDeploymentMap(Set<String> ids) {
|
||||
return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 deploymentId 对应的 ProcessDefinition
|
||||
*
|
||||
* @param deploymentId 部署编号
|
||||
* @return 流程定义
|
||||
*/
|
||||
ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);
|
||||
|
||||
/**
|
||||
* 获得 deploymentIds 对应的 ProcessDefinition 数组
|
||||
*
|
||||
* @param deploymentIds 部署编号的数组
|
||||
* @return 流程定义的数组
|
||||
*/
|
||||
List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
|
||||
|
||||
/**
|
||||
* 获得需要创建的流程定义,是否和当前激活的流程定义相等
|
||||
*
|
||||
* @param createReqDTO 创建信息
|
||||
* @return 是否相等
|
||||
*/
|
||||
boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
|
||||
|
||||
/**
|
||||
* 创建流程定义
|
||||
*
|
||||
* @param createReqDTO 创建信息
|
||||
* @return 流程编号
|
||||
*/
|
||||
String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
|
||||
|
||||
/**
|
||||
* 更新流程定义的挂起状态
|
||||
*
|
||||
* @param id 流程定义的编号
|
||||
* @param state 挂起状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
|
||||
*/
|
||||
void updateProcessDefinitionState(String id, Integer state);
|
||||
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 任务分配规则 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskAssignRuleService {
|
||||
|
||||
/**
|
||||
* 获得流程定义的任务分配规则数组
|
||||
*
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @param taskDefinitionKey 流程任务定义的 Key。允许空
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
|
||||
@Nullable String taskDefinitionKey);
|
||||
|
||||
/**
|
||||
* 获得流程模型的任务规则数组
|
||||
*
|
||||
* @param modelId 流程模型的编号
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
|
||||
|
||||
/**
|
||||
* 获得流程定义的任务分配规则数组
|
||||
*
|
||||
* @param modelId 流程模型的编号
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);
|
||||
|
||||
/**
|
||||
* 创建任务分配规则
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
* @return 规则编号
|
||||
*/
|
||||
Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 更新任务分配规则
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
*/
|
||||
void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 判断指定流程模型和流程定义的分配规则是否相等
|
||||
*
|
||||
* @param modelId 流程模型编号
|
||||
* @param processDefinitionId 流程定义编号
|
||||
* @return 是否相等
|
||||
*/
|
||||
boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId);
|
||||
|
||||
/**
|
||||
* 将流程流程模型的任务分配规则,复制一份给流程定义
|
||||
* 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
|
||||
*
|
||||
* @param fromModelId 流程模型编号
|
||||
* @param toProcessDefinitionId 流程定义编号
|
||||
*/
|
||||
void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
|
||||
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmFormConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmFormMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmFormFieldRespDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.FORM_FIELD_REPEAT;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.FORM_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* 动态表单 Service 实现类
|
||||
*
|
||||
* @author 风里雾里
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmFormServiceImpl implements BpmFormService {
|
||||
|
||||
@Resource
|
||||
private BpmFormMapper formMapper;
|
||||
|
||||
@Override
|
||||
public Long createForm(BpmFormCreateReqVO createReqVO) {
|
||||
this.checkFields(createReqVO.getFields());
|
||||
// 插入
|
||||
BpmFormDO form = BpmFormConvert.INSTANCE.convert(createReqVO);
|
||||
formMapper.insert(form);
|
||||
// 返回
|
||||
return form.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateForm(BpmFormUpdateReqVO updateReqVO) {
|
||||
this.checkFields(updateReqVO.getFields());
|
||||
// 校验存在
|
||||
this.validateFormExists(updateReqVO.getId());
|
||||
// 更新
|
||||
BpmFormDO updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO);
|
||||
formMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteForm(Long id) {
|
||||
// 校验存在
|
||||
this.validateFormExists(id);
|
||||
// 删除
|
||||
formMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateFormExists(Long id) {
|
||||
if (formMapper.selectById(id) == null) {
|
||||
throw exception(FORM_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmFormDO getForm(Long id) {
|
||||
return formMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmFormDO> getFormList() {
|
||||
return formMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmFormDO> getFormList(Collection<Long> ids) {
|
||||
return formMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO) {
|
||||
return formMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 Field,避免 field 重复
|
||||
*
|
||||
* @param fields field 数组
|
||||
*/
|
||||
private void checkFields(List<String> fields) {
|
||||
Map<String, String> fieldMap = new HashMap<>(); // key 是 vModel,value 是 label
|
||||
for (String field : fields) {
|
||||
BpmFormFieldRespDTO fieldDTO = JsonUtils.parseObject(field, BpmFormFieldRespDTO.class);
|
||||
Assert.notNull(fieldDTO);
|
||||
String oldLabel = fieldMap.put(fieldDTO.getVModel(), fieldDTO.getLabel());
|
||||
// 如果不存在,则直接返回
|
||||
if (oldLabel == null) {
|
||||
continue;
|
||||
}
|
||||
// 如果存在,则报错
|
||||
throw exception(FORM_FIELD_REPEAT, oldLabel, fieldDTO.getLabel(), fieldDTO.getVModel());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,305 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ModelQuery;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* 流程定义实现
|
||||
* 主要进行 Activiti {@link Model} 的维护
|
||||
*
|
||||
* @author yunlongn
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmModelServiceImpl implements BpmModelService {
|
||||
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
@Resource
|
||||
private BpmFormService formService;
|
||||
@Resource
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskAssignRuleService taskAssignRuleService;
|
||||
|
||||
@Override
|
||||
public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
|
||||
ModelQuery modelQuery = repositoryService.createModelQuery();
|
||||
if (StrUtil.isNotBlank(pageVO.getKey())) {
|
||||
modelQuery.modelKey(pageVO.getKey());
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageVO.getName())) {
|
||||
modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageVO.getCategory())) {
|
||||
modelQuery.modelCategory(pageVO.getCategory());
|
||||
}
|
||||
// 执行查询
|
||||
List<Model> models = modelQuery.orderByCreateTime().desc()
|
||||
.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
|
||||
|
||||
// 获得 Form Map
|
||||
Set<Long> formIds = CollectionUtils.convertSet(models, model -> {
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
return metaInfo != null ? metaInfo.getFormId() : null;
|
||||
});
|
||||
Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
|
||||
|
||||
// 获得 Deployment Map
|
||||
Set<String> deploymentIds = new HashSet<>();
|
||||
models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
|
||||
Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
|
||||
// 获得 ProcessDefinition Map
|
||||
List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
|
||||
Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
|
||||
|
||||
// 拼接结果
|
||||
long modelCount = modelQuery.count();
|
||||
return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmModelRespVO getModel(String id) {
|
||||
Model model = repositoryService.getModel(id);
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);
|
||||
// 拼接 bpmn XML
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
|
||||
modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
|
||||
return modelRespVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {
|
||||
checkKeyNCName(createReqVO.getKey());
|
||||
// 校验流程标识已经存在
|
||||
Model keyModel = this.getModelByKey(createReqVO.getKey());
|
||||
if (keyModel != null) {
|
||||
throw exception(MODEL_KEY_EXISTS, createReqVO.getKey());
|
||||
}
|
||||
|
||||
// 创建流程定义
|
||||
Model model = repositoryService.newModel();
|
||||
BpmModelConvert.INSTANCE.copy(model, createReqVO);
|
||||
// 保存流程定义
|
||||
repositoryService.saveModel(model);
|
||||
// 保存 BPMN XML
|
||||
saveModelBpmnXml(model, bpmnXml);
|
||||
return model.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public void updateModel(BpmModelUpdateReqVO updateReqVO) {
|
||||
// 校验流程模型存在
|
||||
Model model = repositoryService.getModel(updateReqVO.getId());
|
||||
if (model == null) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 修改流程定义
|
||||
BpmModelConvert.INSTANCE.copy(model, updateReqVO);
|
||||
// 更新模型
|
||||
repositoryService.saveModel(model);
|
||||
// 更新 BPMN XML
|
||||
saveModelBpmnXml(model, updateReqVO.getBpmnXml());
|
||||
}
|
||||
|
||||
private void saveModelBpmnXml(Model model, String bpmnXml) {
|
||||
if (StrUtil.isEmpty(bpmnXml)) {
|
||||
return;
|
||||
}
|
||||
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public void deployModel(String id) {
|
||||
// 校验流程模型存在
|
||||
Model model = repositoryService.getModel(id);
|
||||
if (ObjectUtils.isEmpty(model)) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// 校验流程图
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
|
||||
if (bpmnBytes == null) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
|
||||
// 校验表单已配
|
||||
BpmFormDO form = checkFormConfig(model);
|
||||
// 校验任务分配规则已配置
|
||||
checkTaskAssignRuleAllConfig(id);
|
||||
|
||||
// 校验模型是否发生修改。如果未修改,则不允许创建
|
||||
BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);
|
||||
if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
|
||||
ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
|
||||
}
|
||||
}
|
||||
// 创建流程定义
|
||||
String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
||||
|
||||
// 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
|
||||
updateProcessDefinitionSuspended(model.getDeploymentId());
|
||||
|
||||
// 更新 model 的 deploymentId,进行关联
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
|
||||
model.setDeploymentId(definition.getDeploymentId());
|
||||
repositoryService.saveModel(model);
|
||||
|
||||
// 复制任务分配规则
|
||||
taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验流程模型的任务分配规则全部都配置了
|
||||
* 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
|
||||
*
|
||||
* @param id 流程模型编号
|
||||
*/
|
||||
private void checkTaskAssignRuleAllConfig(String id) {
|
||||
// 一个用户任务都没配置,所以无需配置规则
|
||||
List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
|
||||
if (CollUtil.isEmpty(taskAssignRules)) {
|
||||
return;
|
||||
}
|
||||
// 校验未配置规则的任务
|
||||
taskAssignRules.forEach(rule -> {
|
||||
if (CollUtil.isEmpty(rule.getOptions())) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验流程表单已配置
|
||||
*
|
||||
* @param model 流程模型
|
||||
* @return 流程表单
|
||||
*/
|
||||
private BpmFormDO checkFormConfig(Model model) {
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
if (metaInfo == null || metaInfo.getFormType() == null) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
|
||||
}
|
||||
// 校验表单存在
|
||||
if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
|
||||
BpmFormDO form = formService.getForm(metaInfo.getFormId());
|
||||
if (form == null) {
|
||||
throw exception(FORM_NOT_EXISTS);
|
||||
}
|
||||
return form;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteModel(String id) {
|
||||
// 校验流程模型存在
|
||||
Model model = repositoryService.getModel(id);
|
||||
if (model == null) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// 执行删除
|
||||
repositoryService.deleteModel(id);
|
||||
// 禁用流程实例
|
||||
updateProcessDefinitionSuspended(model.getDeploymentId());
|
||||
}
|
||||
|
||||
private void updateProcessDefinitionSuspended(String deploymentId) {
|
||||
if (StrUtil.isEmpty(deploymentId)) {
|
||||
return;
|
||||
}
|
||||
ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(deploymentId);
|
||||
if (oldDefinition == null) {
|
||||
return;
|
||||
}
|
||||
processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModelState(String id, Integer state) {
|
||||
// 校验流程模型存在
|
||||
Model model = repositoryService.getModel(id);
|
||||
if (model == null) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// 校验流程定义存在
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
if (definition == null) {
|
||||
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmnModel getBpmnModel(String id) {
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
|
||||
if (ArrayUtil.isEmpty(bpmnBytes)) {
|
||||
return null;
|
||||
}
|
||||
return ActivitiUtils.buildBpmnModel(bpmnBytes);
|
||||
}
|
||||
|
||||
private Model getModelByKey(String key) {
|
||||
return repositoryService.createModelQuery().modelKey(key).singleResult();
|
||||
}
|
||||
|
||||
private void checkKeyNCName(String key) {
|
||||
if (!ValidationUtils.isXmlNCName(key)) {
|
||||
throw exception(MODEL_KEY_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,265 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmProcessDefinitionConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.repository.ProcessDefinitionQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
/**
|
||||
* 流程定义实现
|
||||
* 主要进行 Activiti {@link ProcessDefinition} 和 {@link Deployment} 的维护
|
||||
*
|
||||
* @author yunlongn
|
||||
* @author ZJQ
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
|
||||
|
||||
private static final String BPMN_FILE_SUFFIX = ".bpmn";
|
||||
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
@Resource
|
||||
private BpmFormService bpmFormService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessDefinitionExtMapper processDefinitionMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
|
||||
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
|
||||
if (StrUtil.isNotBlank(pageVO.getKey())) {
|
||||
definitionQuery.processDefinitionKey(pageVO.getKey());
|
||||
}
|
||||
// 执行查询
|
||||
List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc()
|
||||
.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
|
||||
if (CollUtil.isEmpty(processDefinitions)) {
|
||||
return new PageResult<>(emptyList(), definitionQuery.count());
|
||||
}
|
||||
|
||||
// 获得 Deployment Map
|
||||
Set<String> deploymentIds = new HashSet<>();
|
||||
processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));
|
||||
Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
|
||||
|
||||
// 获得 BpmProcessDefinitionDO Map
|
||||
List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
|
||||
convertList(processDefinitions, ProcessDefinition::getId));
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
|
||||
BpmProcessDefinitionExtDO::getProcessDefinitionId);
|
||||
|
||||
// 获得 Form Map
|
||||
Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId);
|
||||
Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
|
||||
|
||||
// 拼接结果
|
||||
long definitionCount = definitionQuery.count();
|
||||
return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
|
||||
processDefinitionDOMap, formMap), definitionCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) {
|
||||
// 拼接查询条件
|
||||
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
|
||||
if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) {
|
||||
definitionQuery.suspended();
|
||||
} else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {
|
||||
definitionQuery.active();
|
||||
}
|
||||
// 执行查询
|
||||
List<ProcessDefinition> processDefinitions = definitionQuery.list();
|
||||
|
||||
// 获得 BpmProcessDefinitionDO Map
|
||||
List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
|
||||
convertList(processDefinitions, ProcessDefinition::getId));
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
|
||||
BpmProcessDefinitionExtDO::getProcessDefinitionId);
|
||||
// 执行查询,并返回
|
||||
return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessDefinitionBpmnXML(String id) {
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(id);
|
||||
if (bpmnModel == null) {
|
||||
return null;
|
||||
}
|
||||
return ActivitiUtils.getBpmnXml(bpmnModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmnModel getBpmnModel(String processDefinitionId) {
|
||||
return repositoryService.getBpmnModel(processDefinitionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDefinition getProcessDefinition(String id) {
|
||||
return repositoryService.getProcessDefinition(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDefinition getProcessDefinition2(String id) {
|
||||
return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDefinition getActiveProcessDefinition(String key) {
|
||||
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {
|
||||
return processDefinitionMapper.selectByProcessDefinitionId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deployment getDeployment(String id) {
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
return null;
|
||||
}
|
||||
return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Deployment> getDeployments(Set<String> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return emptyList();
|
||||
}
|
||||
List<Deployment> list = new ArrayList<>(ids.size());
|
||||
for (String id : ids) {
|
||||
addIfNotNull(list, getDeployment(id));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
|
||||
if (StrUtil.isEmpty(deploymentId)) {
|
||||
return null;
|
||||
}
|
||||
return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) {
|
||||
if (CollUtil.isEmpty(deploymentIds)) {
|
||||
return emptyList();
|
||||
}
|
||||
return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProcessDefinitionEquals(BpmProcessDefinitionCreateReqDTO createReqDTO) {
|
||||
// 校验 name、description 是否更新
|
||||
ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey());
|
||||
if (oldProcessDefinition == null) {
|
||||
return false;
|
||||
}
|
||||
BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId());
|
||||
if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName())
|
||||
|| !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription())
|
||||
|| !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) {
|
||||
return false;
|
||||
}
|
||||
// 校验 form 信息是否更新
|
||||
if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType())
|
||||
|| !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId())
|
||||
|| !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf())
|
||||
|| !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields())
|
||||
|| !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath())
|
||||
|| !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) {
|
||||
return false;
|
||||
}
|
||||
// 校验 BPMN XML 信息
|
||||
BpmnModel newModel = ActivitiUtils.buildBpmnModel(createReqDTO.getBpmnBytes());
|
||||
BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
|
||||
if (!ActivitiUtils.equals(oldModel, newModel)) {
|
||||
return false;
|
||||
}
|
||||
// 最终发现都一致,则返回 true
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public String createProcessDefinition(BpmProcessDefinitionCreateReqDTO createReqDTO) {
|
||||
// 创建 Deployment 部署
|
||||
Deployment deploy = repositoryService.createDeployment()
|
||||
.key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
|
||||
.addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
|
||||
.deploy();
|
||||
|
||||
// 设置 ProcessDefinition 的 category 分类
|
||||
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
|
||||
repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory());
|
||||
// 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定
|
||||
// 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。
|
||||
// 否则,会导致 ProcessDefinition 的分页无法查询到。
|
||||
if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) {
|
||||
throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey());
|
||||
}
|
||||
if (!Objects.equals(definition.getName(), createReqDTO.getName())) {
|
||||
throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName());
|
||||
}
|
||||
|
||||
// 插入拓展表
|
||||
BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)
|
||||
.setProcessDefinitionId(definition.getId());
|
||||
processDefinitionMapper.insert(definitionDO);
|
||||
return definition.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessDefinitionState(String id, Integer state) {
|
||||
// 激活
|
||||
if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
|
||||
repositoryService.activateProcessDefinitionById(id, false, null);
|
||||
return;
|
||||
}
|
||||
// 挂起
|
||||
if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
|
||||
// suspendProcessInstances = false,进行中的任务,不进行挂起。
|
||||
// 原因:只要新的流程不允许发起即可,老流程继续可以执行。
|
||||
repositoryService.suspendProcessDefinitionById(id, false, null);
|
||||
return;
|
||||
}
|
||||
log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,203 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmTaskAssignRuleConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dict.SysDictDataService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants.BPM_TASK_ASSIGN_RULE_TYPE;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* BPM 任务分配规则 Service 实现类
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
|
||||
@Resource
|
||||
private BpmTaskAssignRuleMapper taskRuleMapper;
|
||||
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmModelService modelService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
private SysRoleService roleService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
@Resource
|
||||
private SysPostService postService;
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Resource
|
||||
private SysDictDataService dictDataService;
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
|
||||
String taskDefinitionKey) {
|
||||
return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {
|
||||
return taskRuleMapper.selectListByModelId(modelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {
|
||||
// 获得规则
|
||||
List<BpmTaskAssignRuleDO> rules = Collections.emptyList();
|
||||
BpmnModel model = null;
|
||||
if (StrUtil.isNotEmpty(modelId)) {
|
||||
rules = getTaskAssignRuleListByModelId(modelId);
|
||||
model = modelService.getBpmnModel(modelId);
|
||||
} else if (StrUtil.isNotEmpty(processDefinitionId)) {
|
||||
rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);
|
||||
model = processDefinitionService.getBpmnModel(processDefinitionId);
|
||||
}
|
||||
if (model == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 获得用户任务,只有用户任务才可以设置分配规则
|
||||
List<UserTask> userTasks = ActivitiUtils.getBpmnModelElements(model, UserTask.class);
|
||||
if (CollUtil.isEmpty(userTasks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 转换数据
|
||||
return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createTaskAssignRule(BpmTaskAssignRuleCreateReqVO reqVO) {
|
||||
// 校验参数
|
||||
validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
|
||||
// 校验是否已经配置
|
||||
BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(
|
||||
reqVO.getModelId(), reqVO.getTaskDefinitionKey());
|
||||
if (existRule != null) {
|
||||
throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
|
||||
}
|
||||
|
||||
// 存储
|
||||
BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
|
||||
.setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
|
||||
taskRuleMapper.insert(rule);
|
||||
return rule.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskAssignRule(BpmTaskAssignRuleUpdateReqVO reqVO) {
|
||||
// 校验参数
|
||||
validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
|
||||
// 校验是否存在
|
||||
BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId());
|
||||
if (existRule == null) {
|
||||
throw exception(TASK_ASSIGN_RULE_NOT_EXISTS);
|
||||
}
|
||||
// 只允许修改流程模型的规则
|
||||
if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) {
|
||||
throw exception(TASK_UPDATE_FAIL_NOT_MODEL);
|
||||
}
|
||||
|
||||
// 执行更新
|
||||
taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) {
|
||||
// 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性
|
||||
List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null);
|
||||
List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId);
|
||||
if (modelRules.size() != processInstanceRules.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 遍历,匹配对应的规则
|
||||
Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,
|
||||
BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
|
||||
for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
|
||||
BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
|
||||
if (processInstanceRule == null) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())
|
||||
|| !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
|
||||
List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
|
||||
if (CollUtil.isEmpty(rules)) {
|
||||
return;
|
||||
}
|
||||
// 开始复制
|
||||
List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
|
||||
newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
|
||||
.setCreateTime(null).setUpdateTime(null));
|
||||
taskRuleMapper.insertBatch(newRules);
|
||||
}
|
||||
|
||||
private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
|
||||
if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
|
||||
roleService.validRoles(options);
|
||||
} else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
|
||||
BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
|
||||
deptService.validDepts(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {
|
||||
postService.validPosts(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) {
|
||||
userService.validUsers(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) {
|
||||
userGroupService.validUserGroups(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {
|
||||
dictDataService.validDictDatas(SysDictTypeConstants.BPM_TASK_ASSIGN_SCRIPT,
|
||||
CollectionUtils.convertSet(options, String::valueOf));
|
||||
} else {
|
||||
throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,114 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmUserGroupConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmUserGroupMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.USER_GROUP_IS_DISABLE;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.USER_GROUP_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.USER_IS_DISABLE;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.USER_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* 用户组 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmUserGroupServiceImpl implements BpmUserGroupService {
|
||||
|
||||
@Resource
|
||||
private BpmUserGroupMapper userGroupMapper;
|
||||
|
||||
@Override
|
||||
public Long createUserGroup(BpmUserGroupCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
BpmUserGroupDO userGroup = BpmUserGroupConvert.INSTANCE.convert(createReqVO);
|
||||
userGroupMapper.insert(userGroup);
|
||||
// 返回
|
||||
return userGroup.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserGroup(BpmUserGroupUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
this.validateUserGroupExists(updateReqVO.getId());
|
||||
// 更新
|
||||
BpmUserGroupDO updateObj = BpmUserGroupConvert.INSTANCE.convert(updateReqVO);
|
||||
userGroupMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUserGroup(Long id) {
|
||||
// 校验存在
|
||||
this.validateUserGroupExists(id);
|
||||
// 删除
|
||||
userGroupMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateUserGroupExists(Long id) {
|
||||
if (userGroupMapper.selectById(id) == null) {
|
||||
throw exception(USER_GROUP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmUserGroupDO getUserGroup(Long id) {
|
||||
return userGroupMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmUserGroupDO> getUserGroupList(Collection<Long> ids) {
|
||||
return userGroupMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmUserGroupDO> getUserGroupListByStatus(Integer status) {
|
||||
return userGroupMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmUserGroupDO> getUserGroupPage(BpmUserGroupPageReqVO pageReqVO) {
|
||||
return userGroupMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validUserGroups(Set<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得用户组信息
|
||||
List<BpmUserGroupDO> userGroups = userGroupMapper.selectBatchIds(ids);
|
||||
Map<Long, BpmUserGroupDO> userGroupMap = CollectionUtils.convertMap(userGroups, BpmUserGroupDO::getId);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
BpmUserGroupDO userGroup = userGroupMap.get(id);
|
||||
if (userGroup == null) {
|
||||
throw exception(USER_GROUP_NOT_EXISTS);
|
||||
}
|
||||
if (!CommonStatusEnum.ENABLE.getStatus().equals(userGroup.getStatus())) {
|
||||
throw exception(USER_GROUP_IS_DISABLE, userGroup.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.message;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* BPM 消息 Service 接口
|
||||
*
|
||||
* TODO 芋艿:未来支持消息的可配置;不同的流程,在什么场景下,需要发送什么消息,消息的内容是什么;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmMessageService {
|
||||
|
||||
/**
|
||||
* 发送流程实例被通过的消息
|
||||
*
|
||||
* @param reqDTO 发送信息
|
||||
*/
|
||||
void sendMessageWhenProcessInstanceApprove(@Valid BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO);
|
||||
|
||||
|
||||
/**
|
||||
* 发送流程实例被不通过的消息
|
||||
*
|
||||
* @param reqDTO 发送信息
|
||||
*/
|
||||
void sendMessageWhenProcessInstanceReject(@Valid BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 发送任务被分配的消息
|
||||
*
|
||||
* @param reqDTO 发送信息
|
||||
*/
|
||||
void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO);
|
||||
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.message.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.message.BpmMessageEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* BPM 消息 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
|
||||
@Resource
|
||||
private SysSmsCoreService smsCoreService;
|
||||
|
||||
@Value("${yudao.url.admin-ui}")
|
||||
private String adminUiUrl;
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenProcessInstanceApprove(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO) {
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
|
||||
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
|
||||
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getStartUserId(),
|
||||
BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsCode(), templateParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) {
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
|
||||
templateParams.put("comment", reqDTO.getComment());
|
||||
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
|
||||
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getStartUserId(),
|
||||
BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsCode(), templateParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
|
||||
templateParams.put("taskName", reqDTO.getTaskName());
|
||||
templateParams.put("startUserNickname", reqDTO.getStartUserNickname());
|
||||
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
|
||||
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getAssigneeUserId(),
|
||||
BpmMessageEnum.TASK_ASSIGNED.getSmsCode(), templateParams);
|
||||
}
|
||||
|
||||
private String getProcessInstanceDetailUrl(String taskId) {
|
||||
return adminUiUrl + "bpm/process-instance/detail?id=" + taskId;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.oa.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.oa.BpmOALeaveConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.BpmOALeaveDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.BpmOALeaveMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.BpmOALeaveService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.dto.BpmProcessInstanceCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* OA 请假申请 Service 实现类
|
||||
*
|
||||
* @author jason
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmOALeaveServiceImpl implements BpmOALeaveService {
|
||||
|
||||
/**
|
||||
* OA 请假对应的流程定义 KEY
|
||||
*/
|
||||
public static final String PROCESS_KEY = "oa_leave";
|
||||
|
||||
@Resource
|
||||
private BpmOALeaveMapper leaveMapper;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createLeave(Long userId, BpmOALeaveCreateReqVO createReqVO) {
|
||||
// 插入 OA 请假单
|
||||
long day = DateUtil.betweenDay(createReqVO.getStartTime(), createReqVO.getEndTime(), false);
|
||||
BpmOALeaveDO leave = BpmOALeaveConvert.INSTANCE.convert(createReqVO).setUserId(userId).setDay(day)
|
||||
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||
leaveMapper.insert(leave);
|
||||
|
||||
// 发起 BPM 流程
|
||||
Map<String, Object> processInstanceVariables = new HashMap<>();
|
||||
processInstanceVariables.put("day", day);
|
||||
String processInstanceId = processInstanceService.createProcessInstance(userId,
|
||||
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
|
||||
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(leave.getId())));
|
||||
|
||||
// 将工作流的编号,更新到 OA 请假单中
|
||||
leaveMapper.updateById(new BpmOALeaveDO().setId(leave.getId()).setProcessInstanceId(processInstanceId));
|
||||
return leave.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLeaveResult(Long id, Integer result) {
|
||||
leaveMapper.updateById(new BpmOALeaveDO().setId(id).setResult(result));
|
||||
}
|
||||
|
||||
private void validateLeaveExists(Long id) {
|
||||
if (leaveMapper.selectById(id) == null) {
|
||||
throw exception(OA_LEAVE_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmOALeaveDO getLeave(Long id) {
|
||||
return leaveMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmOALeaveDO> getLeavePage(Long userId, BpmOALeavePageReqVO pageReqVO) {
|
||||
return leaveMapper.selectPage(userId, pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.oa.listener;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEvent;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventListener;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.BpmOALeaveService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.impl.BpmOALeaveServiceImpl;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* OA 请假单的结果的监听器实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmOALeaveResultListener extends BpmProcessInstanceResultEventListener {
|
||||
|
||||
@Resource
|
||||
private BpmOALeaveService leaveService;
|
||||
|
||||
@Override
|
||||
protected String getProcessDefinitionKey() {
|
||||
return BpmOALeaveServiceImpl.PROCESS_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEvent(BpmProcessInstanceResultEvent event) {
|
||||
leaveService.updateLeaveResult(Long.parseLong(event.getBusinessKey()), event.getResult());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 活动实例 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmActivityService {
|
||||
|
||||
/**
|
||||
* 获得指定流程实例的活动实例列表
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 活动实例列表
|
||||
*/
|
||||
List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 生成指定流程实例的高亮流程图,只高亮进行中的任务
|
||||
*
|
||||
* 友情提示,非该方法的注释。如果想实现更高级的高亮流程图(当前节点红色 + 完成节点为绿色),可参考如下内容:
|
||||
* 博客一:https://blog.csdn.net/qq_40109075/article/details/110939639
|
||||
* 博客二:https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramGenerator.java
|
||||
* 这里不实现的原理,需要自定义实现 ProcessDiagramGenerator 和 ProcessDiagramCanvas,代码量有点大
|
||||
*
|
||||
* 如果你想实现高亮已完成的任务,可参考 https://blog.csdn.net/qiuxinfa123/article/details/119579863 博客。不过测试下来,貌似不太对~
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 图的字节数组
|
||||
*/
|
||||
byte[] generateHighlightDiagram(String processInstanceId);
|
||||
|
||||
}
|
||||
@ -1,166 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.dto.BpmProcessInstanceCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 流程实例 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmProcessInstanceService {
|
||||
|
||||
/**
|
||||
* 创建流程实例(提供给前端)
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param createReqVO 创建信息
|
||||
* @return 实例的编号
|
||||
*/
|
||||
String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 创建流程实例(提供给内部)
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param createReqDTO 创建信息
|
||||
* @return 实例的编号
|
||||
*/
|
||||
String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO);
|
||||
|
||||
/**
|
||||
* 取消流程实例
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param cancelReqVO 取消信息
|
||||
*/
|
||||
void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
|
||||
|
||||
/**
|
||||
* 删除流程实例
|
||||
*
|
||||
* @param id 流程编号
|
||||
* @param reason 删除原因。可选 {@link BpmProcessInstanceDeleteReasonEnum}
|
||||
*/
|
||||
@Deprecated
|
||||
void deleteProcessInstance(String id, String reason);
|
||||
|
||||
/**
|
||||
* 获得流程实例的分页
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 流程实例的分页
|
||||
*/
|
||||
PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
|
||||
@Valid BpmProcessInstanceMyPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得流程实例 VO 信息
|
||||
*
|
||||
* @param id 流程实例的编号
|
||||
* @return 流程实例
|
||||
*/
|
||||
BpmProcessInstanceRespVO getProcessInstanceVO(String id);
|
||||
|
||||
/**
|
||||
* 获得流程实例
|
||||
*
|
||||
* @param id 流程实例的编号
|
||||
* @return 流程实例
|
||||
*/
|
||||
ProcessInstance getProcessInstance(String id);
|
||||
|
||||
/**
|
||||
* 获得流程实例列表
|
||||
*
|
||||
* @param ids 流程实例的编号集合
|
||||
* @return 流程实例列表
|
||||
*/
|
||||
List<ProcessInstance> getProcessInstances(Set<String> ids);
|
||||
|
||||
/**
|
||||
* 获得流程实例 Map
|
||||
*
|
||||
* @param ids 流程实例的编号集合
|
||||
* @return 流程实例列表 Map
|
||||
*/
|
||||
default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {
|
||||
return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得历史的流程实例
|
||||
*
|
||||
* @param id 流程实例的编号
|
||||
* @return 历史的流程实例
|
||||
*/
|
||||
HistoricProcessInstance getHistoricProcessInstance(String id);
|
||||
|
||||
/**
|
||||
* 获得历史的流程实例列表
|
||||
*
|
||||
* @param ids 流程实例的编号集合
|
||||
* @return 历史的流程实例列表
|
||||
*/
|
||||
List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids);
|
||||
|
||||
/**
|
||||
* 获得历史的流程实例 Map
|
||||
*
|
||||
* @param ids 流程实例的编号集合
|
||||
* @return 历史的流程实例列表 Map
|
||||
*/
|
||||
default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) {
|
||||
return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 ProcessInstance 拓展记录
|
||||
*
|
||||
* @param instance 流程任务
|
||||
*/
|
||||
void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);
|
||||
|
||||
/**
|
||||
* 更新 ProcessInstance 拓展记录
|
||||
*
|
||||
* @param instance 流程任务
|
||||
*/
|
||||
void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);
|
||||
|
||||
/**
|
||||
* 更新 ProcessInstance 拓展记录为取消
|
||||
*
|
||||
* @param instance 流程任务
|
||||
* @param reason 取消原因
|
||||
*/
|
||||
void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance, String reason);
|
||||
|
||||
/**
|
||||
* 更新 ProcessInstance 拓展记录为完成
|
||||
*
|
||||
* @param instance 流程任务
|
||||
*/
|
||||
void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance);
|
||||
|
||||
/**
|
||||
* 更新 ProcessInstance 拓展记录为不通过
|
||||
*
|
||||
* @param id 流程编号
|
||||
* @param comment 理由。例如说,审批不通过时,需要传递该值
|
||||
*/
|
||||
void updateProcessInstanceExtReject(String id, String comment);
|
||||
|
||||
}
|
||||
@ -1,159 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.task.Task;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程任务实例 Service 接口
|
||||
*
|
||||
* @author jason
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskService {
|
||||
|
||||
/**
|
||||
* 获得指定流程实例的 Running 进行中的流程任务列表
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
*/
|
||||
List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 获得指令流程实例的流程任务列表,包括所有状态的
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 流程任务列表
|
||||
*/
|
||||
List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 获得流程任务列表
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 流程任务列表
|
||||
*/
|
||||
List<Task> getTasksByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 获得流程任务列表
|
||||
*
|
||||
* @param processInstanceIds 流程实例的编号数组
|
||||
* @return 流程任务列表
|
||||
*/
|
||||
List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);
|
||||
|
||||
/**
|
||||
* 获得流程任务 Map
|
||||
*
|
||||
* @param processInstanceIds 流程实例的编号数组
|
||||
* @return 流程任务 Map
|
||||
*/
|
||||
default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {
|
||||
return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),
|
||||
Task::getProcessInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得待办的流程任务分页
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 流程任务分页
|
||||
*/
|
||||
PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得已办的流程任务分页
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 流程任务分页
|
||||
*/
|
||||
PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 将流程任务分配给指定用户
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param reqVO 分配请求
|
||||
*/
|
||||
void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 将流程任务分配给指定用户
|
||||
*
|
||||
* @param id 流程任务编号
|
||||
* @param userId 用户编号
|
||||
*/
|
||||
void updateTaskAssignee(String id, Long userId);
|
||||
|
||||
/**
|
||||
* 通过任务
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param reqVO 通过请求
|
||||
*/
|
||||
void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 不通过任务
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param reqVO 不通过请求
|
||||
*/
|
||||
void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
|
||||
|
||||
// ========== Task 拓展表相关 ==========
|
||||
|
||||
/**
|
||||
* 创建 Task 拓展记录
|
||||
*
|
||||
* @param task 任务实体
|
||||
*/
|
||||
void createTaskExt(org.activiti.api.task.model.Task task);
|
||||
|
||||
/**
|
||||
* 更新 Task 拓展记录
|
||||
*
|
||||
* @param task 任务实体
|
||||
*/
|
||||
void updateTaskExt(org.activiti.api.task.model.Task task);
|
||||
|
||||
/**
|
||||
* 更新 Task 拓展记录,并发送通知
|
||||
*
|
||||
* @param task 任务实体
|
||||
*/
|
||||
void updateTaskExtAssign(org.activiti.api.task.model.Task task);
|
||||
|
||||
/**
|
||||
* 更新 Task 拓展记录为取消
|
||||
*
|
||||
* @param task 任务实体
|
||||
*/
|
||||
void updateTaskExtCancel(org.activiti.api.task.model.Task task);
|
||||
|
||||
/**
|
||||
* 更新 Task 拓展记录为完成
|
||||
*
|
||||
* @param task 任务实体
|
||||
*/
|
||||
void updateTaskExtComplete(org.activiti.api.task.model.Task task);
|
||||
|
||||
/**
|
||||
* 获得流程实例对应的 Task 拓展列表
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return Task 拓展列表
|
||||
*/
|
||||
List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
|
||||
}
|
||||
@ -1,93 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmActivityConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.history.HistoricActivityInstance;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.activiti.image.ProcessDiagramGenerator;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* BPM 活动实例 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Validated
|
||||
public class BpmActivityServiceImpl implements BpmActivityService {
|
||||
|
||||
private static final String FONT_NAME = "宋体";
|
||||
|
||||
@Resource
|
||||
private ProcessDiagramGenerator processDiagramGenerator;
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@Resource
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@Override
|
||||
public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
|
||||
List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(processInstanceId).list();
|
||||
return BpmActivityConvert.INSTANCE.convertList(activityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] generateHighlightDiagram(String processInstanceId) {
|
||||
// 获得流程实例
|
||||
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
|
||||
if (processInstance == null) {
|
||||
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
// 获得流程定义的 BPMN 模型
|
||||
BpmnModel bpmnModel = processDefinitionService.getBpmnModel(processInstance.getProcessDefinitionId());
|
||||
if (bpmnModel == null) {
|
||||
throw exception(PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 如果流程已经结束,则无进行中的任务,无法高亮
|
||||
// 如果流程未结束,才需要高亮
|
||||
List<String> highLightedActivities = Collections.emptyList();
|
||||
if (processInstance.getEndTime() == null) {
|
||||
List<Task> tasks = taskService.getTasksByProcessInstanceId(processInstanceId);
|
||||
highLightedActivities = CollectionUtils.convertList(tasks, Task::getTaskDefinitionKey);
|
||||
}
|
||||
|
||||
// 生成高亮流程图
|
||||
InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivities, Collections.emptyList(),
|
||||
FONT_NAME, FONT_NAME, FONT_NAME);
|
||||
return IoUtil.readBytes(inputStream);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,315 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEvent;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventListener;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventPublisher;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.dto.BpmProcessInstanceCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 流程实例 Service 实现类
|
||||
*
|
||||
* ProcessDefinition & ProcessInstance & Execution & Task 的关系:
|
||||
* 1. https://blog.csdn.net/bobozai86/article/details/105210414
|
||||
*
|
||||
* HistoricProcessInstance & ProcessInstance 的关系:
|
||||
* 1.https://my.oschina.net/843294669/blog/719024
|
||||
* 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
|
||||
|
||||
@Resource
|
||||
private RuntimeService runtimeService;
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskService taskService;
|
||||
@Resource
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
private BpmMessageService messageService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceExtMapper processInstanceExtMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) {
|
||||
// 获得流程定义
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
|
||||
// 发起流程
|
||||
return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqDTO createReqDTO) {
|
||||
// 获得流程定义
|
||||
ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
|
||||
// 发起流程
|
||||
return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey());
|
||||
}
|
||||
|
||||
private String createProcessInstance0(Long userId, ProcessDefinition definition,
|
||||
Map<String, Object> variables, String businessKey) {
|
||||
// 校验流程定义
|
||||
if (definition == null) {
|
||||
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
|
||||
}
|
||||
if (definition.isSuspended()) {
|
||||
throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
|
||||
}
|
||||
|
||||
// 创建流程实例
|
||||
ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);
|
||||
// 设置流程名字
|
||||
runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
|
||||
|
||||
// 补全流程实例的拓展表
|
||||
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
|
||||
.setFormVariables(variables));
|
||||
|
||||
// 添加初始的评论 TODO 芋艿:在思考下
|
||||
// Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();
|
||||
// if (task != null) {
|
||||
// SysUserDO user = userService.getUser(userId);
|
||||
// Assert.notNull(user, "用户({})不存在", userId);
|
||||
// String type = "normal";
|
||||
// taskService.addComment(task.getId(), instance.getProcessInstanceId(), type,
|
||||
// String.format("%s 发起流程申请", user.getNickname()));
|
||||
// }
|
||||
return instance.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
|
||||
// 校验流程实例存在
|
||||
ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
|
||||
if (instance == null) {
|
||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
|
||||
}
|
||||
// 只能取消自己的
|
||||
if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
|
||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
|
||||
}
|
||||
|
||||
// 通过删除流程实例,实现流程实例的取消
|
||||
runtimeService.deleteProcessInstance(cancelReqVO.getId(),
|
||||
BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProcessInstance(String id, String reason) {
|
||||
runtimeService.deleteProcessInstance(id, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
|
||||
BpmProcessInstanceMyPageReqVO pageReqVO) {
|
||||
// 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
|
||||
PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return new PageResult<>(pageResult.getTotal());
|
||||
}
|
||||
|
||||
// 获得流程 Task Map
|
||||
List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);
|
||||
Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);
|
||||
// 转换返回
|
||||
return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {
|
||||
// 获得流程实例
|
||||
HistoricProcessInstance processInstance = getHistoricProcessInstance(id);
|
||||
if (processInstance == null) {
|
||||
return null;
|
||||
}
|
||||
BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);
|
||||
Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
|
||||
|
||||
// 获得流程定义
|
||||
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
|
||||
processInstance.getProcessDefinitionId());
|
||||
Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
|
||||
BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
|
||||
processInstance.getProcessDefinitionId());
|
||||
Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
|
||||
String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());
|
||||
|
||||
// 获得 User
|
||||
SysUserDO startUser = userService.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
SysDeptDO dept = null;
|
||||
if (startUser != null) {
|
||||
dept = deptService.getDept(startUser.getDeptId());
|
||||
}
|
||||
|
||||
// 拼接结果
|
||||
return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,
|
||||
processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessInstance> getProcessInstances(Set<String> ids) {
|
||||
return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessInstance getProcessInstance(String id) {
|
||||
return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得历史的流程实例
|
||||
*
|
||||
* @param id 流程实例的编号
|
||||
* @return 历史的流程实例
|
||||
*/
|
||||
@Override
|
||||
public HistoricProcessInstance getHistoricProcessInstance(String id) {
|
||||
return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {
|
||||
return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {
|
||||
// 获得流程定义
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());
|
||||
// 插入 BpmProcessInstanceExtDO 对象
|
||||
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||
.setCategory(definition.getCategory())
|
||||
.setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())
|
||||
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||
processInstanceExtMapper.insert(instanceExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {
|
||||
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance);
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance, String reason) {
|
||||
// 判断是否为 Reject 不通过。如果是,则不进行更新
|
||||
if (BpmProcessInstanceDeleteReasonEnum.isRejectReason(reason)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 需要主动查询,因为 instance 只有 id 属性
|
||||
// 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
|
||||
HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
|
||||
// 更新拓展表
|
||||
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||
.setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
|
||||
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
|
||||
.setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
|
||||
// 发送流程实例的状态事件
|
||||
processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
|
||||
BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance) {
|
||||
// 需要主动查询,因为 instance 只有 id 属性
|
||||
// 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
|
||||
HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
|
||||
// 更新拓展表
|
||||
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||
.setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
|
||||
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
|
||||
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
|
||||
// 发送流程被通过的消息
|
||||
messageService.sendMessageWhenProcessInstanceApprove(BpmMessageConvert.INSTANCE.convert(instance));
|
||||
|
||||
// 发送流程实例的状态事件
|
||||
processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
|
||||
BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateProcessInstanceExtReject(String id, String comment) {
|
||||
// 需要主动查询,因为 instance 只有 id 属性
|
||||
ProcessInstance processInstance = getProcessInstance(id);
|
||||
// 删除流程实例,以实现驳回任务时,取消整个审批流程
|
||||
deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment)));
|
||||
|
||||
// 更新 status + result
|
||||
// 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,
|
||||
// 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的
|
||||
BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)
|
||||
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
|
||||
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
|
||||
// 发送流程被不通过的消息
|
||||
messageService.sendMessageWhenProcessInstanceReject(BpmMessageConvert.INSTANCE.convert(processInstance, comment));
|
||||
|
||||
// 发送流程实例的状态事件
|
||||
processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
|
||||
BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,321 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.TaskService;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.history.HistoricTaskInstance;
|
||||
import org.activiti.engine.history.HistoricTaskInstanceQuery;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.activiti.engine.task.TaskQuery;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 流程任务实例 Service 实现类
|
||||
*
|
||||
* @author jason
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
|
||||
@Resource
|
||||
private TaskService taskService;
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@Resource
|
||||
private BpmMessageService messageService;
|
||||
|
||||
@Resource
|
||||
private BpmTaskExtMapper taskExtMapper;
|
||||
|
||||
@Override
|
||||
public List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId) {
|
||||
return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) {
|
||||
// 获得任务列表
|
||||
List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序
|
||||
.list();
|
||||
if (CollUtil.isEmpty(tasks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 获得 TaskExtDO Map
|
||||
List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
|
||||
Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
|
||||
// 获得 ProcessInstance Map
|
||||
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
|
||||
// 获得 User Map
|
||||
Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee()));
|
||||
userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(userIds);
|
||||
// 获得 Dept Map
|
||||
Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(convertSet(userMap.values(), SysUserDO::getDeptId));
|
||||
|
||||
// 拼接数据
|
||||
return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Task> getTasksByProcessInstanceId(String processInstanceId) {
|
||||
if (StrUtil.isEmpty(processInstanceId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {
|
||||
if (CollUtil.isEmpty(processInstanceIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
|
||||
// 查询待办任务
|
||||
TaskQuery taskQuery = taskService.createTaskQuery()
|
||||
.taskAssignee(String.valueOf(userId)) // 分配给自己
|
||||
.orderByTaskCreateTime().desc(); // 创建时间倒序
|
||||
if (StrUtil.isNotBlank(pageVO.getName())) {
|
||||
taskQuery.taskNameLike("%" + pageVO.getName() + "%");
|
||||
}
|
||||
if (pageVO.getBeginCreateTime() != null) {
|
||||
taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());
|
||||
}
|
||||
if (pageVO.getEndCreateTime() != null) {
|
||||
taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());
|
||||
}
|
||||
// 执行查询
|
||||
List<Task> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
|
||||
if (CollUtil.isEmpty(tasks)) {
|
||||
return PageResult.empty(taskQuery.count());
|
||||
}
|
||||
|
||||
// 获得 ProcessInstance Map
|
||||
Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(
|
||||
convertSet(tasks, Task::getProcessInstanceId));
|
||||
// 获得 User Map
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(
|
||||
convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
|
||||
// 拼接结果
|
||||
return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),
|
||||
taskQuery.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) {
|
||||
// 查询已办任务
|
||||
HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
|
||||
.finished() // 已完成
|
||||
.taskAssignee(String.valueOf(userId)) // 分配给自己
|
||||
.orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
|
||||
if (StrUtil.isNotBlank(pageVO.getName())) {
|
||||
taskQuery.taskNameLike("%" + pageVO.getName() + "%");
|
||||
}
|
||||
if (pageVO.getBeginCreateTime() != null) {
|
||||
taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());
|
||||
}
|
||||
if (pageVO.getEndCreateTime() != null) {
|
||||
taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());
|
||||
}
|
||||
// 执行查询
|
||||
List<HistoricTaskInstance> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
|
||||
if (CollUtil.isEmpty(tasks)) {
|
||||
return PageResult.empty(taskQuery.count());
|
||||
}
|
||||
|
||||
// 获得 TaskExtDO Map
|
||||
List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
|
||||
Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
|
||||
// 获得 ProcessInstance Map
|
||||
Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
|
||||
convertSet(tasks, HistoricTaskInstance::getProcessInstanceId));
|
||||
// 获得 User Map
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(
|
||||
convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
|
||||
// 拼接结果
|
||||
return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),
|
||||
taskQuery.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) {
|
||||
// 校验任务存在
|
||||
Task task = getTask(reqVO.getId());
|
||||
if (task == null) {
|
||||
throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
|
||||
}
|
||||
if (!ActivitiUtils.equals(task.getAssignee(), userId)) {
|
||||
throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
|
||||
// 更新负责人
|
||||
updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskAssignee(String id, Long userId) {
|
||||
taskService.setAssignee(id, String.valueOf(userId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void approveTask(Long userId, BpmTaskApproveReqVO reqVO) {
|
||||
// 校验任务存在
|
||||
Task task = getTask(reqVO.getId());
|
||||
if (task == null) {
|
||||
throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
|
||||
}
|
||||
if (!ActivitiUtils.equals(task.getAssignee(), userId)) {
|
||||
throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
// 校验流程实例存在
|
||||
ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
|
||||
if (instance == null) {
|
||||
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 完成任务,审批通过
|
||||
taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿:variables 的选择
|
||||
// 更新任务拓展表为通过
|
||||
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
|
||||
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment()));
|
||||
|
||||
// TODO 芋艿:添加评论
|
||||
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) {
|
||||
// 校验任务存在
|
||||
Task task = getTask(reqVO.getId());
|
||||
if (task == null) {
|
||||
throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
|
||||
}
|
||||
if (!ActivitiUtils.equals(task.getAssignee(), userId)) {
|
||||
throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
// 校验流程实例存在
|
||||
ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
|
||||
if (instance == null) {
|
||||
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 更新流程实例为不通过
|
||||
processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment());
|
||||
|
||||
// 更新任务拓展表为不通过
|
||||
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
|
||||
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment()));
|
||||
|
||||
// TODO 芋艿:添加评论
|
||||
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
||||
}
|
||||
|
||||
private Task getTask(String id) {
|
||||
return taskService.createTaskQuery().taskId(id).singleResult();
|
||||
}
|
||||
|
||||
// ========== Task 拓展表相关 ==========
|
||||
|
||||
@Override
|
||||
public void createTaskExt(org.activiti.api.task.model.Task task) {
|
||||
// 插入 BpmTaskExtDO 记录
|
||||
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||
taskExtMapper.insert(taskExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskExt(org.activiti.api.task.model.Task task) {
|
||||
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task);
|
||||
taskExtMapper.updateByTaskId(taskExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskExtAssign(org.activiti.api.task.model.Task task) {
|
||||
// 更新
|
||||
updateTaskExt(task);
|
||||
// 发送通知。由于 Activiti 操作是在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
|
||||
SysUserDO startUser = userService.getUser(Long.valueOf(processInstance.getStartUserId()));
|
||||
messageService.sendMessageWhenTaskAssigned(BpmMessageConvert.INSTANCE.convert(processInstance, startUser, task));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {
|
||||
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||
.setEndTime(new Date()) // 由于 Task 里没有办法拿到 endTime,所以这里设置
|
||||
.setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
|
||||
taskExtMapper.updateByTaskId(taskExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskExtComplete(org.activiti.api.task.model.Task task) {
|
||||
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||
.setEndTime(new Date()) // 此时不能使用 task 的 completeData,因为还是空的。
|
||||
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
|
||||
taskExtMapper.updateByTaskId(taskExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId) {
|
||||
return taskExtMapper.selectListByProcessInstanceId(processInstanceId);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
/**
|
||||
* task 包下,存放的都是 xxx 实例。例如说:
|
||||
* 1. ProcessInstance 是 ProcessDefinition 创建而来的实例;
|
||||
* 2. TaskInstance 是 TaskDefinition 创建而来的实例;
|
||||
* 3. ActivityInstance 是 BPMN 流程图的每个元素创建的实例;
|
||||
*
|
||||
* 考虑到 Task 和 Activity 可以比较明确表示名字,所以对应的 Service 就没有使用 Instance 后缀~
|
||||
* 嘿嘿,其实也是实现到比较后面的阶段,所以就暂时没去统一和修改了~
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
@ -1,105 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.config.InfConfigDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.convert.config.InfConfigConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.service.config.InfConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_SENSITIVE;
|
||||
|
||||
@Api(tags = "参数配置")
|
||||
@RestController
|
||||
@RequestMapping("/infra/config")
|
||||
@Validated
|
||||
public class InfConfigController {
|
||||
|
||||
@Resource
|
||||
private InfConfigService configService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:create')")
|
||||
public CommonResult<Long> createConfig(@Valid @RequestBody InfConfigCreateReqVO reqVO) {
|
||||
return success(configService.createConfig(reqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("修改参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:update')")
|
||||
public CommonResult<Boolean> updateConfig(@Valid @RequestBody InfConfigUpdateReqVO reqVO) {
|
||||
configService.updateConfig(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除参数配置")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
|
||||
public CommonResult<Boolean> deleteConfig(@RequestParam("id") Long id) {
|
||||
configService.deleteConfig(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@ApiOperation("获得参数配置")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
||||
public CommonResult<InfConfigRespVO> getConfig(@RequestParam("id") Long id) {
|
||||
return success(InfConfigConvert.INSTANCE.convert(configService.getConfig(id)));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get-value-by-key")
|
||||
@ApiOperation(value = "根据参数键名查询参数值", notes = "敏感配置,不允许返回给前端")
|
||||
@ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class)
|
||||
public CommonResult<String> getConfigKey(@RequestParam("key") String key) {
|
||||
InfConfigDO config = configService.getConfigByKey(key);
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
if (config.getSensitive()) {
|
||||
throw exception(CONFIG_GET_VALUE_ERROR_IF_SENSITIVE);
|
||||
}
|
||||
return success(config.getValue());
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获取参数配置分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
||||
public CommonResult<PageResult<InfConfigRespVO>> getConfigPage(@Valid InfConfigPageReqVO reqVO) {
|
||||
PageResult<InfConfigDO> page = configService.getConfigPage(reqVO);
|
||||
return success(InfConfigConvert.INSTANCE.convertPage(page));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@ApiOperation("导出参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportSysConfig(@Valid InfConfigExportReqVO reqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<InfConfigDO> list = configService.getConfigList(reqVO);
|
||||
// 拼接数据
|
||||
List<InfConfigExcelVO> datas = InfConfigConvert.INSTANCE.convertList(list);
|
||||
// 输出
|
||||
ExcelUtils.write(response, "参数配置.xls", "数据", InfConfigExcelVO.class, datas);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 参数配置 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class InfConfigBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "参数分组", required = true, example = "biz")
|
||||
@NotEmpty(message = "参数分组不能为空")
|
||||
@Size(max = 50, message = "参数名称不能超过50个字符")
|
||||
private String group;
|
||||
|
||||
@ApiModelProperty(value = "参数名称", required = true, example = "数据库名")
|
||||
@NotBlank(message = "参数名称不能为空")
|
||||
@Size(max = 100, message = "参数名称不能超过100个字符")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "参数键值", required = true, example = "1024")
|
||||
@NotBlank(message = "参数键值不能为空")
|
||||
@Size(max = 500, message = "参数键值长度不能超过500个字符")
|
||||
private String value;
|
||||
|
||||
@ApiModelProperty(value = "是否敏感", required = true, example = "true")
|
||||
@NotNull(message = "是否敏感不能为空")
|
||||
private Boolean sensitive;
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "备注一下很帅气!")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
@ApiModel("参数配置创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InfConfigCreateReqVO extends InfConfigBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
|
||||
@NotBlank(message = "参数键名长度不能为空")
|
||||
@Size(max = 100, message = "参数键名长度不能超过100个字符")
|
||||
private String key;
|
||||
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 参数配置 Excel 导出响应 VO
|
||||
*/
|
||||
@Data
|
||||
public class InfConfigExcelVO {
|
||||
|
||||
@ExcelProperty("参数配置序号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("参数键名")
|
||||
private String key;
|
||||
|
||||
@ExcelProperty("参数分组")
|
||||
private String group;
|
||||
|
||||
@ExcelProperty("参数名称")
|
||||
private String name;
|
||||
|
||||
@ExcelProperty("参数键值")
|
||||
private String value;
|
||||
|
||||
@ExcelProperty(value = "参数类型", converter = DictConvert.class)
|
||||
@DictFormat(SysDictTypeConstants.CONFIG_TYPE)
|
||||
private Integer type;
|
||||
|
||||
@ExcelProperty(value = "是否敏感", converter = DictConvert.class)
|
||||
@DictFormat(SysDictTypeConstants.BOOLEAN_STRING)
|
||||
private Boolean sensitive;
|
||||
|
||||
@ExcelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("参数配置导出 Request VO")
|
||||
@Data
|
||||
public class InfConfigExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "参数名称", example = "模糊匹配")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date beginTime;
|
||||
|
||||
@ApiModelProperty(value = "结束时间", example = "2020-10-24 23:59:59")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date endTime;
|
||||
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("参数配置分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfConfigPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "参数名称", example = "模糊匹配")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date beginTime;
|
||||
|
||||
@ApiModelProperty(value = "结束时间", example = "2020-10-24 23:59:59")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date endTime;
|
||||
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("参数配置信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InfConfigRespVO extends InfConfigBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
|
||||
@NotBlank(message = "参数键名长度不能为空")
|
||||
@Size(max = 100, message = "参数键名长度不能超过100个字符")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty(value = "参数类型", required = true, example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.config.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("参数配置创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfConfigUpdateReqVO extends InfConfigBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
|
||||
@NotNull(message = "参数配置编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
@ -1,155 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.doc;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.smallbun.screw.core.Configuration;
|
||||
import cn.smallbun.screw.core.engine.EngineConfig;
|
||||
import cn.smallbun.screw.core.engine.EngineFileType;
|
||||
import cn.smallbun.screw.core.engine.EngineTemplateType;
|
||||
import cn.smallbun.screw.core.execute.DocumentationExecute;
|
||||
import cn.smallbun.screw.core.process.ProcessConfig;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Api(tags = "数据库文档")
|
||||
@RestController
|
||||
@RequestMapping("/infra/db-doc")
|
||||
public class InfDbDocController {
|
||||
|
||||
@Resource
|
||||
private DynamicDataSourceProperties dynamicDataSourceProperties;
|
||||
|
||||
private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator
|
||||
+ "db-doc";
|
||||
private static final String DOC_FILE_NAME = "数据库文档";
|
||||
private static final String DOC_VERSION = "1.0.0";
|
||||
private static final String DOC_DESCRIPTION = "文档描述";
|
||||
|
||||
@GetMapping("/export-html")
|
||||
@ApiOperation("导出 html 格式的数据文档")
|
||||
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||
public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.HTML, deleteFile, response);
|
||||
}
|
||||
|
||||
@GetMapping("/export-word")
|
||||
@ApiOperation("导出 word 格式的数据文档")
|
||||
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||
public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.WORD, deleteFile, response);
|
||||
}
|
||||
|
||||
@GetMapping("/export-markdown")
|
||||
@ApiOperation("导出 markdown 格式的数据文档")
|
||||
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||
public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.MD, deleteFile, response);
|
||||
}
|
||||
|
||||
private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
|
||||
String filePath = doExportFile(fileOutputType, docFileName);
|
||||
String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
|
||||
try {
|
||||
// 读取,返回
|
||||
ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
|
||||
} finally {
|
||||
handleDeleteFile(deleteFile, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出文件,返回文件路径
|
||||
*
|
||||
* @param fileOutputType 文件类型
|
||||
* @param fileName 文件名, 无需 ".docx" 等文件后缀
|
||||
* @return 生成的文件所在路径
|
||||
*/
|
||||
private String doExportFile(EngineFileType fileOutputType, String fileName) {
|
||||
try (HikariDataSource dataSource = buildDataSource()) {
|
||||
// 创建 screw 的配置
|
||||
Configuration config = Configuration.builder()
|
||||
.version(DOC_VERSION) // 版本
|
||||
.description(DOC_DESCRIPTION) // 描述
|
||||
.dataSource(dataSource) // 数据源
|
||||
.engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
|
||||
.produceConfig(buildProcessConfig()) // 处理配置
|
||||
.build();
|
||||
|
||||
// 执行 screw,生成数据库文档
|
||||
new DocumentationExecute(config).execute();
|
||||
|
||||
return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeleteFile(Boolean deleteFile, String filePath) {
|
||||
if (!deleteFile) {
|
||||
return;
|
||||
}
|
||||
FileUtil.del(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据源
|
||||
*/
|
||||
// TODO 芋艿:screw 暂时不支持 druid,尴尬
|
||||
private HikariDataSource buildDataSource() {
|
||||
// 获得 DataSource 数据源,目前只支持首个
|
||||
String primary = dynamicDataSourceProperties.getPrimary();
|
||||
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
|
||||
// 创建 HikariConfig 配置类
|
||||
HikariConfig hikariConfig = new HikariConfig();
|
||||
hikariConfig.setJdbcUrl(dataSourceProperty.getUrl());
|
||||
hikariConfig.setUsername(dataSourceProperty.getUsername());
|
||||
hikariConfig.setPassword(dataSourceProperty.getPassword());
|
||||
hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
|
||||
// 创建数据源
|
||||
return new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 screw 的引擎配置
|
||||
*/
|
||||
private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
|
||||
return EngineConfig.builder()
|
||||
.fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
|
||||
.openOutputDir(false) // 打开目录
|
||||
.fileType(fileOutputType) // 文件类型
|
||||
.produceType(EngineTemplateType.freemarker) // 文件类型
|
||||
.fileName(docFileName) // 自定义文件名称
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 screw 的处理配置,一般可忽略
|
||||
* 指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
|
||||
*/
|
||||
private static ProcessConfig buildProcessConfig() {
|
||||
return ProcessConfig.builder()
|
||||
.ignoreTablePrefix(Collections.singletonList("QRTZ_")) // 忽略表前缀
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.file;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.service.file.InfFileService;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.file.vo.InfFilePageReqVO;
|
||||
import cn.iocoder.yudao.coreservice.modules.infra.controller.file.vo.InfFileRespVO;
|
||||
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.convert.file.InfFileConvert;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "文件存储")
|
||||
@RestController
|
||||
@RequestMapping("/infra/file")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class InfFileController {
|
||||
|
||||
@Resource
|
||||
private InfFileService fileService;
|
||||
@Resource
|
||||
private InfFileCoreService fileCoreService;
|
||||
|
||||
@PostMapping("/upload")
|
||||
@ApiOperation("上传文件")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class),
|
||||
@ApiImplicitParam(name = "path", value = "文件路径", example = "yudaoyuanma.png", dataTypeClass = String.class)
|
||||
})
|
||||
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("path") String path) throws IOException {
|
||||
return success(fileCoreService.createFile(path, IoUtil.readBytes(file.getInputStream())));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除文件")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = String.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
|
||||
public CommonResult<Boolean> deleteFile(@RequestParam("id") String id) {
|
||||
fileCoreService.deleteFile(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get/{path}")
|
||||
@ApiOperation("下载文件")
|
||||
@ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
|
||||
public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException {
|
||||
TenantContextHolder.setNullTenantId();
|
||||
InfFileDO file = fileCoreService.getFile(path);
|
||||
if (file == null) {
|
||||
log.warn("[getFile][path({}) 文件不存在]", path);
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
ServletUtils.writeAttachment(response, path, file.getContent());
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得文件分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:query')")
|
||||
public CommonResult<PageResult<InfFileRespVO>> getFilePage(@Valid InfFilePageReqVO pageVO) {
|
||||
PageResult<InfFileDO> pageResult = fileService.getFilePage(pageVO);
|
||||
return success(InfFileConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.file.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("文件分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfFilePageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "文件路径", example = "yudao", notes = "模糊匹配")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "文件类型", example = "jpg", notes = "模糊匹配")
|
||||
private String type;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
||||
@ -1,145 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.framework.quartz.core.util.CronUtils;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.convert.job.InfJobConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.dal.dataobject.job.InfJobDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.service.job.InfJobService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Api(tags = "定时任务")
|
||||
@RestController
|
||||
@RequestMapping("/infra/job")
|
||||
@Validated
|
||||
public class InfJobController {
|
||||
|
||||
@Resource
|
||||
private InfJobService jobService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建定时任务")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:create')")
|
||||
public CommonResult<Long> createJob(@Valid @RequestBody InfJobCreateReqVO createReqVO)
|
||||
throws SchedulerException {
|
||||
return success(jobService.createJob(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新定时任务")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:update')")
|
||||
public CommonResult<Boolean> updateJob(@Valid @RequestBody InfJobUpdateReqVO updateReqVO)
|
||||
throws SchedulerException {
|
||||
jobService.updateJob(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@ApiOperation("更新定时任务的状态")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
|
||||
@ApiImplicitParam(name = "status", value = "状态", required = true, example = "1", dataTypeClass = Integer.class),
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:update')")
|
||||
public CommonResult<Boolean> updateJobStatus(@RequestParam(value = "id") Long id, @RequestParam("status") Integer status)
|
||||
throws SchedulerException {
|
||||
jobService.updateJobStatus(id, status);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除定时任务")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:delete')")
|
||||
public CommonResult<Boolean> deleteJob(@RequestParam("id") Long id)
|
||||
throws SchedulerException {
|
||||
jobService.deleteJob(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/trigger")
|
||||
@ApiOperation("触发定时任务")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:trigger')")
|
||||
public CommonResult<Boolean> triggerJob(@RequestParam("id") Long id) throws SchedulerException {
|
||||
jobService.triggerJob(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得定时任务")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<InfJobRespVO> getJob(@RequestParam("id") Long id) {
|
||||
InfJobDO job = jobService.getJob(id);
|
||||
return success(InfJobConvert.INSTANCE.convert(job));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得定时任务列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<List<InfJobRespVO>> getJobList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<InfJobDO> list = jobService.getJobList(ids);
|
||||
return success(InfJobConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得定时任务分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<PageResult<InfJobRespVO>> getJobPage(@Valid InfJobPageReqVO pageVO) {
|
||||
PageResult<InfJobDO> pageResult = jobService.getJobPage(pageVO);
|
||||
return success(InfJobConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出定时任务 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportJobExcel(@Valid InfJobExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<InfJobDO> list = jobService.getJobList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<InfJobExcelVO> datas = InfJobConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "定时任务.xls", "数据", InfJobExcelVO.class, datas);
|
||||
}
|
||||
|
||||
@GetMapping("/get_next_times")
|
||||
@ApiOperation("获得定时任务的下 n 次执行时间")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
|
||||
@ApiImplicitParam(name = "count", value = "数量", example = "5", dataTypeClass = Long.class)
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<List<Date>> getJobNextTimes(@RequestParam("id") Long id,
|
||||
@RequestParam(value = "count", required = false, defaultValue = "5") Integer count) {
|
||||
InfJobDO job = jobService.getJob(id);
|
||||
if (job == null) {
|
||||
return success(Collections.emptyList());
|
||||
}
|
||||
return success(CronUtils.getNextTimes(job.getCronExpression(), count));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.log.InfJobLogExcelVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.log.InfJobLogExportReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.log.InfJobLogPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.log.InfJobLogRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.convert.job.InfJobLogConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.dal.dataobject.job.InfJobLogDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.service.job.InfJobLogService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Api(tags = "定时任务日志")
|
||||
@RestController
|
||||
@RequestMapping("/infra/job-log")
|
||||
@Validated
|
||||
public class InfJobLogController {
|
||||
|
||||
@Resource
|
||||
private InfJobLogService jobLogService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得定时任务日志")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<InfJobLogRespVO> getJobLog(@RequestParam("id") Long id) {
|
||||
InfJobLogDO jobLog = jobLogService.getJobLog(id);
|
||||
return success(InfJobLogConvert.INSTANCE.convert(jobLog));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得定时任务日志列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<List<InfJobLogRespVO>> getJobLogList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<InfJobLogDO> list = jobLogService.getJobLogList(ids);
|
||||
return success(InfJobLogConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得定时任务日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
||||
public CommonResult<PageResult<InfJobLogRespVO>> getJobLogPage(@Valid InfJobLogPageReqVO pageVO) {
|
||||
PageResult<InfJobLogDO> pageResult = jobLogService.getJobLogPage(pageVO);
|
||||
return success(InfJobLogConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出定时任务日志 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('infra:job:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportJobLogExcel(@Valid InfJobLogExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<InfJobLogDO> list = jobLogService.getJobLogList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<InfJobLogExcelVO> datas = InfJobLogConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "任务日志.xls", "数据", InfJobLogExcelVO.class, datas);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 定时任务 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class InfJobBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "任务名称", required = true, example = "测试任务")
|
||||
@NotNull(message = "任务名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "处理器的参数", example = "yudao")
|
||||
private String handlerParam;
|
||||
|
||||
@ApiModelProperty(value = "CRON 表达式", required = true, example = "0/10 * * * * ? *")
|
||||
@NotNull(message = "CRON 表达式不能为空")
|
||||
private String cronExpression;
|
||||
|
||||
@ApiModelProperty(value = "重试次数", required = true, example = "3")
|
||||
@NotNull(message = "重试次数不能为空")
|
||||
private Integer retryCount;
|
||||
|
||||
@ApiModelProperty(value = "重试间隔", required = true, example = "1000")
|
||||
@NotNull(message = "重试间隔不能为空")
|
||||
private Integer retryInterval;
|
||||
|
||||
@ApiModelProperty(value = "监控超时时间", example = "1000")
|
||||
private Integer monitorTimeout;
|
||||
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("定时任务创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfJobCreateReqVO extends InfJobBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
|
||||
@NotNull(message = "处理器的名字不能为空")
|
||||
private String handlerName;
|
||||
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.infra.enums.InfDictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 定时任务 Excel VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class InfJobExcelVO {
|
||||
|
||||
@ExcelProperty("任务编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("任务名称")
|
||||
private String name;
|
||||
|
||||
@ExcelProperty(value = "任务状态", converter = DictConvert.class)
|
||||
@DictFormat(InfDictTypeConstants.JOB_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty("处理器的名字")
|
||||
private String handlerName;
|
||||
|
||||
@ExcelProperty("处理器的参数")
|
||||
private String handlerParam;
|
||||
|
||||
@ExcelProperty("CRON 表达式")
|
||||
private String cronExpression;
|
||||
|
||||
@ExcelProperty("最后一次执行的开始时间")
|
||||
private Date executeBeginTime;
|
||||
|
||||
@ExcelProperty("最后一次执行的结束时间")
|
||||
private Date executeEndTime;
|
||||
|
||||
@ExcelProperty("上一次触发时间")
|
||||
private Date firePrevTime;
|
||||
|
||||
@ExcelProperty("下一次触发时间")
|
||||
private Date fireNextTime;
|
||||
|
||||
@ExcelProperty("监控超时时间")
|
||||
private Integer monitorTimeout;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(value = "定时任务 Excel 导出 Request VO", description = "参数和 InfJobPageReqVO 是一致的")
|
||||
@Data
|
||||
public class InfJobExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 InfJobStatusEnum 枚举")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配")
|
||||
private String handlerName;
|
||||
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ApiModel("定时任务分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfJobPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 InfJobStatusEnum 枚举")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配")
|
||||
private String handlerName;
|
||||
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.infra.controller.job.vo.job;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("定时任务 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class InfJobRespVO extends InfJobBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "任务状态", required = true, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
|
||||
@NotNull(message = "处理器的名字不能为空")
|
||||
private String handlerName;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user