Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into pay_extension

 Conflicts:
	sql/ruoyi-vue-pro.sql
	yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysDictTypeConstants.java
	yudao-admin-server/src/main/resources/application-local.yaml
	yudao-admin-server/src/main/resources/application.yaml
	yudao-admin-server/src/test/resources/sql/clean.sql
	yudao-admin-server/src/test/resources/sql/create_tables.sql
	yudao-admin-ui/src/utils/dict.js
This commit is contained in:
YunaiV 2022-01-23 04:12:34 +08:00
commit 2860108a7d
547 changed files with 34242 additions and 6477 deletions

View File

@ -4,22 +4,36 @@
> 有任何问题,或者想要的功能,可以在 _Issues_ 中提给艿艿。
* 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)。
* 后端采用 Spring Boot、MySQL、Redis。
* 权限认证使用 Spring Security & Token支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) ,正在支持 Vue 3 + ElementUI Plus 最新方案。
* 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson。
* 权限认证使用 Spring Security & Token & Redis支持多终端、多种用户的认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制,本地缓存提升性能。
* 工作流使用 Activiti ,支持动态表单、在线设计流程、多种任务分配方式。
* 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档。
## 在线体验
演示地址:<http://dashboard.yudao.iocoder.cn>
* 账号密码admin/admin123
文档地址:<http://www.iocoder.cn/categories/Yudao/>
* [《如何搭建环境》](http://www.iocoder.cn/categories/Yudao/?yudao)
> 未来会补充文档和视频,方便胖友冲冲冲!
## 内置功能
分成三种内置功能:
分成种内置功能:
* 系统功能
* 工作流程
* 支付系统
* 基础设施
* 研发工具
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
>
> 额外新增的功能,我们使用 🚀 标记。
> * 额外新增的功能,我们使用 🚀 标记。
> * 重新实现的功能,我们使用 ⭐️ 标记。
🙂 所有功能,都通过 **单元测试** 保证高质量。
@ -28,29 +42,46 @@
| | 功能 | 描述 |
| --- | --- | --- |
| | 用户管理 | 用户是系统操作者,该功能主要完成系统用户配置 |
| | 在线用户 | 当前系统中活跃用户状态监控,支持手动踢下线 |
| ⭐️ | 在线用户 | 当前系统中活跃用户状态监控,支持手动踢下线 |
| | 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 |
| | 菜单管理 | 配置系统菜单,操作权限,按钮权限标识等 |
| | 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等,本地缓存提供性能 |
| | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 |
| | 岗位管理 | 配置系统用户所属担任职务 |
| | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 |
| 🚀 | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 |
| | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 |
| 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、云片等主流短信平台 |
| 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 |
| | 登录日志 | 系统登录日志记录查询,包含登录异常 |
| ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 |
| 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 |
| | 通知公告 | 系统通知公告信息发布维护 |
### 工作流程
| | 功能 | 描述 |
| --- | --- | --- |
| 🚀 | 流程模型 | 配置工作流的流程模型,支持文件导入与在线设计流程图,提供 7 种任务分配规则 |
| 🚀 | 流程表单 | 拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件 |
| 🚀 | 用户分组 | 自定义用户分组,可用于工作流的审批分组 |
| 🚀 | 我的流程 | 查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线 |
| 🚀 | 待办任务 | 查看自己【未】审批的工作任务,支持通过、不通过、转发、委派、退回等操作 |
| 🚀 | 已办任务 | 查看自己【已】审批的工作任务,未来会支持回退操作 |
| 🚀 | OA 请假 | 作为业务自定义接入工作流的使用案例,只需创建请求对应的工作流程,即可进行审批 |
### 支付系统
正在测试中,核心功能已经开发完毕。
### 基础设施
| | 功能 | 描述 |
| --- | --- | --- |
| 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 |
| | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 |
| ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 |
| 🚀 | 文件服务 | 支持本地文件存储,同时支持兼容 Amazon S3 协议的云服务、开源组件 |
| 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 |
| | MySQL 监控 | 监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈 |
| | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 |
| 🚀 | 消息队列 | 基于 Redis 实现消息队列Stream 提供集群消费Pub/Sub 提供广播消费 |
| 🚀 |Java 监控 | 基于 Spring Boot Admin 实现 Java 应用的监控 |
| 🚀 | 链路追踪 | 接入 SkyWalking 组件,实现链路追踪 |
| 🚀 | 日志中心 | 接入 SkyWalking 组件,实现日志中心 |
@ -67,17 +98,7 @@
| 🚀 | 代码生成 |前后端代码的生成Java、Vue、SQL、单元测试支持 CRUD 下载 |
| 🚀 | 系统接口 | 基于 Swagger 自动生成相关的 RESTful API 接口文档 |
| 🚀 | 数据库文档 | 基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式 |
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码 |
## 在线体验
演示地址:<http://dashboard.yudao.iocoder.cn>
* 账号密码admin/admin123
文档地址:<http://www.iocoder.cn/categories/Yudao/>
* [《如何搭建环境》](http://www.iocoder.cn/categories/Yudao/?yudao)
> 未来会补充文档和视频,方便胖友冲冲冲!
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 |
## 技术栈
@ -107,6 +128,7 @@
| [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) |
| [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) |
@ -132,7 +154,7 @@
| 模块 | biu | biu | biu |
| --- | --- | --- | --- |
| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg) |
| 用户 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg) | ![在线用户](https://static.iocoder.cn/images/ruoyi-vue-pro/在线用户.jpg) | - |
| 用户 & 租户 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg) | ![在线用户](https://static.iocoder.cn/images/ruoyi-vue-pro/在线用户.jpg) | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg) |
| 部门 & 岗位 | ![部门管理](https://static.iocoder.cn/images/ruoyi-vue-pro/部门管理.jpg) | ![岗位管理](https://static.iocoder.cn/images/ruoyi-vue-pro/岗位管理.jpg) | - |
| 菜单 & 角色 | ![菜单管理](https://static.iocoder.cn/images/ruoyi-vue-pro/菜单管理.jpg) | ![角色管理](https://static.iocoder.cn/images/ruoyi-vue-pro/角色管理.jpg) | - |
| 审计日志 | ![操作日志](https://static.iocoder.cn/images/ruoyi-vue-pro/操作日志.jpg) | ![登录日志](https://static.iocoder.cn/images/ruoyi-vue-pro/登录日志.jpg) | - |
@ -140,6 +162,16 @@
| 字典 | ![字典类型](https://static.iocoder.cn/images/ruoyi-vue-pro/字典类型.jpg) | ![字典数据](https://static.iocoder.cn/images/ruoyi-vue-pro/字典数据.jpg) | - |
| 错误码 & 通知 | ![错误码管理](https://static.iocoder.cn/images/ruoyi-vue-pro/错误码管理.jpg) | ![通知公告](https://static.iocoder.cn/images/ruoyi-vue-pro/通知公告.jpg) | - |
### 工作流程
| 模块 | biu | biu | biu |
| --- | --- | --- | --- |
| 流程模型 | ![流程模型-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-列表.jpg) | ![流程模型-设计](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-设计.jpg) | ![流程模型-定义](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-定义.jpg) |
| 表单 & 分组 | ![流程表单](https://static.iocoder.cn/images/ruoyi-vue-pro/流程表单.jpg) | ![用户分组](https://static.iocoder.cn/images/ruoyi-vue-pro/用户分组.jpg) | - |
| 我的流程 | ![我的流程-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-列表.jpg) | ![我的流程-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-发起.jpg) | ![我的流程-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-详情.jpg) |
| 待办 & 已办 | ![任务列表-审批](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-审批.jpg) | ![任务列表-待办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-待办.jpg) | ![任务列表-已办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-已办.jpg) |
| OA 请假 | ![OA请假-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-列表.jpg) | ![OA请假-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-发起.jpg) | ![OA请假-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-详情.jpg) |
### 基础设施
| 模块 | biu | biu | biu |
@ -154,5 +186,5 @@
| 模块 | biu | biu | biu |
| --- | --- | --- | --- |
| 代码生成 | ![代码生成](https://static.iocoder.cn/images/ruoyi-vue-pro/代码生成.jpg) | ![生成效果](https://static.iocoder.cn/images/ruoyi-vue-pro/生成效果.jpg) | ![表单构建](https://static.iocoder.cn/images/ruoyi-vue-pro/表单构建.jpg) |
| 代码生成 | ![代码生成](https://static.iocoder.cn/images/ruoyi-vue-pro/代码生成.jpg) | ![生成效果](https://static.iocoder.cn/images/ruoyi-vue-pro/生成效果.jpg) | - |
| 文档 | ![系统接口](https://static.iocoder.cn/images/ruoyi-vue-pro/系统接口.jpg) | ![数据库文档](https://static.iocoder.cn/images/ruoyi-vue-pro/数据库文档.jpg) | - |

4380
sql/activiti.sql Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.convert.form.WfFormConvert;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
import cn.iocoder.yudao.adminserver.modules.activiti.service.form.WfFormService;
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 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.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;
// TODO @风里雾里 Os=Wf/os 改成 /wl 开头目前这个模块咱先定位成给工作流用的
@Api(tags = "动态表单")
@RestController
@RequestMapping("/wl/form")
@Validated
public class WlFormController {
@Resource
private WfFormService formService;
@PostMapping("/create")
@ApiOperation("创建动态表单")
@PreAuthorize("@ss.hasPermission('os:form:create')")
public CommonResult<Long> createForm(@Valid @RequestBody WfFormCreateReqVO createReqVO) {
return success(formService.createForm(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新动态表单")
@PreAuthorize("@ss.hasPermission('os:form:update')")
public CommonResult<Boolean> updateForm(@Valid @RequestBody WfFormUpdateReqVO updateReqVO) {
formService.updateForm(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除动态表单")
@ApiImplicitParam(name = "id", value = "编号", required = true)
@PreAuthorize("@ss.hasPermission('os:form:delete')")
public CommonResult<Boolean> deleteForm(@RequestParam("id") Long id) {
formService.deleteForm(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得动态表单")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('os:form:query')")
public CommonResult<WfFormRespVO> getForm(@RequestParam("id") Long id) {
WfForm form = formService.getForm(id);
return success(WfFormConvert.INSTANCE.convert(form));
}
@GetMapping("/list")
@ApiOperation("获得动态表单列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('os:form:query')")
public CommonResult<List<WfFormRespVO>> getFormList(@RequestParam("ids") Collection<Long> ids) {
List<WfForm> list = formService.getFormList(ids);
return success(WfFormConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得动态表单分页")
@PreAuthorize("@ss.hasPermission('os:form:query')")
public CommonResult<PageResult<WfFormRespVO>> getFormPage(@Valid WfFormPageReqVO pageVO) {
PageResult<WfForm> pageResult = formService.getFormPage(pageVO);
return success(WfFormConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出动态表单 Excel")
@PreAuthorize("@ss.hasPermission('os:form:export')")
@OperateLog(type = EXPORT)
public void exportFormExcel(@Valid WfFormExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<WfForm> list = formService.getFormList(exportReqVO);
// 导出 Excel
List<WfFormExcelVO> datas = WfFormConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "动态表单.xls", "数据", WfFormExcelVO.class, datas);
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 动态表单 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class WfFormBaseVO {
@ApiModelProperty(value = "表单名称", required = true)
@NotNull(message = "表单名称不能为空")
private String name;
@ApiModelProperty(value = "商户状态", required = true)
@NotNull(message = "商户状态不能为空")
private Integer status;
@ApiModelProperty(value = "表单JSON")
private String formJson;
@ApiModelProperty(value = "备注")
private String remark;
}

View File

@ -1,12 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
import lombok.*;
import io.swagger.annotations.*;
@ApiModel("动态表单创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WfFormCreateReqVO extends WfFormBaseVO {
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
import lombok.*;
import java.util.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 动态表单 Excel VO
*
* @author 芋艿
*/
@Data
public class WfFormExcelVO {
@ExcelProperty("表单编号")
private Long id;
@ExcelProperty("表单名称")
private String name;
@ExcelProperty("商户状态")
private Integer status;
@ExcelProperty("表单JSON")
private String formJson;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "动态表单 Excel 导出 Request VO", description = "参数和 OsFormPageReqVO 是一致的")
@Data
public class WfFormExportReqVO {
@ApiModelProperty(value = "表单名称")
private String name;
@ApiModelProperty(value = "商户状态")
private Integer status;
@ApiModelProperty(value = "表单JSON")
private String formJson;
@ApiModelProperty(value = "备注")
private String remark;
@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;
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("动态表单更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WfFormUpdateReqVO extends WfFormBaseVO {
@ApiModelProperty(value = "表单编号", required = true)
@NotNull(message = "表单编号不能为空")
private Long id;
}

View File

@ -1,114 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
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.security.core.util.SecurityFrameworkUtils;
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.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;
// TODO @jasonOa=OA 会不会好点名词缩写哈
@Api(tags = "请假申请")
@RestController
@RequestMapping("/oa/leave")
@Validated
public class OaLeaveController {
@Resource
private OaLeaveService leaveService;
@PostMapping("/create")
@ApiOperation("创建请假申请")
@PreAuthorize("@ss.hasPermission('oa:leave:create')")
public CommonResult<Long> createLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
// TODO @芋艿processKey 自己去理解下不过得把 leave 变成枚举
createReqVO.setProcessKey("leave");
return success(leaveService.createLeave(createReqVO));
}
@PostMapping("/form-key/create")
@ApiOperation("创建外置请假申请")
public CommonResult<Long> createFormKeyLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
// TODO @芋艿processKey 自己去理解下不过得把 formkey 变成枚举
createReqVO.setProcessKey("leave-formkey");
return success(leaveService.createLeave(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新请假申请")
@PreAuthorize("@ss.hasPermission('oa:leave:update')")
public CommonResult<Boolean> updateLeave(@Valid @RequestBody OaLeaveUpdateReqVO updateReqVO) {
leaveService.updateLeave(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除请假申请")
@ApiImplicitParam(name = "id", value = "编号", required = true)
@PreAuthorize("@ss.hasPermission('oa:leave:delete')")
public CommonResult<Boolean> deleteLeave(@RequestParam("id") Long id) {
leaveService.deleteLeave(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得请假申请")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('oa:leave:query')")
public CommonResult<OaLeaveRespVO> getLeave(@RequestParam("id") Long id) {
OaLeaveDO leave = leaveService.getLeave(id);
return success(OaLeaveConvert.INSTANCE.convert(leave));
}
@GetMapping("/list")
@ApiOperation("获得请假申请列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('oa:leave:query')")
public CommonResult<List<OaLeaveRespVO>> getLeaveList(@RequestParam("ids") Collection<Long> ids) {
List<OaLeaveDO> list = leaveService.getLeaveList(ids);
return success(OaLeaveConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得请假申请分页")
@PreAuthorize("@ss.hasPermission('oa:leave:query')")
public CommonResult<PageResult<OaLeaveRespVO>> getLeavePage(@Valid OaLeavePageReqVO pageVO) {
//值查询自己申请请假
// TODO @芋艿这里的传值到底前端搞还是后端搞
pageVO.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
PageResult<OaLeaveDO> pageResult = leaveService.getLeavePage(pageVO);
return success(OaLeaveConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出请假申请 Excel")
@PreAuthorize("@ss.hasPermission('oa:leave:export')")
@OperateLog(type = EXPORT)
public void exportLeaveExcel(@Valid OaLeaveExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<OaLeaveDO> list = leaveService.getLeaveList(exportReqVO);
// 导出 Excel
List<OaLeaveExcelVO> datas = OaLeaveConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "请假申请.xls", "数据", OaLeaveExcelVO.class, datas);
}
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 请假申请 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class OaLeaveBaseVO {
@ApiModelProperty(value = "流程id")
private String processInstanceId;
@ApiModelProperty(value = "状态", required = true)
private Integer status;
@ApiModelProperty(value = "申请人id", required = true)
private String userId;
@ApiModelProperty(value = "开始时间", required = true)
@NotNull(message = "开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date startTime;
@ApiModelProperty(value = "结束时间", required = true)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "请假类型")
private String leaveType;
@ApiModelProperty(value = "原因")
private String reason;
@ApiModelProperty(value = "申请时间", required = true)
@NotNull(message = "申请时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date applyTime;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
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 OaLeaveCreateReqVO extends OaLeaveBaseVO {
private String processKey;
}

View File

@ -1,44 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 请假申请 Excel VO
*
* @author 芋艿
*/
@Data
public class OaLeaveExcelVO {
@ExcelProperty("请假表单主键")
private Long id;
@ExcelProperty("流程id")
private String processInstanceId;
@ExcelProperty("状态")
private Integer status;
@ExcelProperty("申请人id")
private String userId;
@ExcelProperty("开始时间")
private Date startTime;
@ExcelProperty("结束时间")
private Date endTime;
@ExcelProperty("请假类型")
private String leaveType;
@ExcelProperty("原因")
private String reason;
@ExcelProperty("申请时间")
private Date applyTime;
}

View File

@ -1,54 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
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(value = "请假申请 Excel 导出 Request VO", description = "参数和 OaLeavePageReqVO 是一致的")
@Data
public class OaLeaveExportReqVO {
@ApiModelProperty(value = "流程id")
private String processInstanceId;
@ApiModelProperty(value = "状态")
private Integer status;
@ApiModelProperty(value = "申请人id")
private String userId;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始开始时间")
private Date beginStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束开始时间")
private Date endStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始结束时间")
private Date beginEndTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束结束时间")
private Date endEndTime;
@ApiModelProperty(value = "请假类型")
private String leaveType;
@ApiModelProperty(value = "原因")
private String reason;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始申请时间")
private Date beginApplyTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束申请时间")
private Date endApplyTime;
}

View File

@ -1,56 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
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 OaLeavePageReqVO extends PageParam {
@ApiModelProperty(value = "流程id")
private String processInstanceId;
@ApiModelProperty(value = "状态")
private Integer status;
@ApiModelProperty(value = "申请人id")
private String userId;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始开始时间")
private Date beginStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束开始时间")
private Date endStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始结束时间")
private Date beginEndTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束结束时间")
private Date endEndTime;
@ApiModelProperty(value = "请假类型")
private String leaveType;
@ApiModelProperty(value = "原因")
private String reason;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始申请时间")
private Date beginApplyTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束申请时间")
private Date endApplyTime;
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("请假申请 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OaLeaveRespVO extends OaLeaveBaseVO {
@ApiModelProperty(value = "请假表单主键", required = true)
private Long id;
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.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;
import java.util.Map;
@ApiModel("请假申请更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OaLeaveUpdateReqVO extends OaLeaveBaseVO {
@ApiModelProperty(value = "请假表单主键", required = true)
@NotNull(message = "请假表单主键不能为空")
private Long id;
// TODO @jsonswagger validator 的注解要加哈
private String taskId;
private String comment;
private Map<String,Object> variables;
// TODO @芋艿variables 的作用是啥
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.engine.RepositoryService;
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;
// TODO @jsonswagger validation 的注解后续要补全下哈可以等 workflow 基本写的差不多之后
@RestController
@RequestMapping("/workflow/process/definition")
public class ProcessDefinitionController {
@Resource
private RepositoryService repositoryService;
@Resource
private ProcessRuntime processRuntime;
@GetMapping(value = "/getStartForm")
public CommonResult<String> getStartForm(@RequestParam("processKey") String processKey){
//这样查似乎有问题 暂时写死
// final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
// processDefinitionKey(processKey).latestVersion().singleResult();
// processRuntime.processDefinition(processDefinition.getId()).getFormKey();
return CommonResult.success("/flow/leave/apply");
}
}

View File

@ -1,60 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
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.ApiOperation;
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;
// TODO @jsonswagger validation 的注解后续要补全下哈可以等 workflow 基本写的差不多之后
@Api(tags = "工作流待办任务")
@RestController
@RequestMapping("/workflow/task")
public class TaskController {
@Resource
private TaskService taskService;
@GetMapping("/todo/page")
@ApiOperation("获取待办任务分页")
public CommonResult<PageResult<TodoTaskRespVO>> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) {
return success(taskService.getTodoTaskPage(pageVO));
}
@GetMapping("/claim")
@ApiOperation("签收任务")
public CommonResult<Boolean> claimTask(@RequestParam("id") String taskId) {
taskService.claimTask(taskId);
return success(true);
}
@PostMapping("/task-steps")
public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) {
return success(taskService.getTaskSteps(taskQuery));
}
@PostMapping("/formKey")
public CommonResult<TodoTaskRespVO> getTaskFormKey(@RequestBody TaskQueryReqVO taskQuery) {
return success(taskService.getTaskFormKey(taskQuery));
}
@PostMapping("/complete")
public CommonResult<Boolean> complete(@RequestBody TaskReqVO taskReq) {
taskService.completeTask(taskReq);
return success(true);
}
@GetMapping("/process/history-steps")
public CommonResult<List<TaskStepVO>> getHistorySteps(@RequestParam("id") String processInstanceId) {
return success(taskService.getHistorySteps(processInstanceId));
}
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ToString
public class TaskHandleVO {
private Object formObject;
private List<TaskStepVO> historyTask;
private String taskVariable;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TaskQueryReqVO {
private String processKey;
private String taskId;
private String businessKey;
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import lombok.Data;
import lombok.ToString;
import java.util.Map;
@Data
@ToString
public class TaskReqVO {
private String taskId;
private Map<String,Object> variables;
private String comment;
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
@Data
@ToString
public class TaskStepVO {
private String stepName;
private Date startTime;
private Date endTime;
private String assignee;
private String comment;
private Integer status;
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ApiModel("待办任务申请分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TodoTaskPageReqVO extends PageParam {
private String assignee;
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ApiModel("待办任务 Response VO")
@Data
@ToString
public class TodoTaskRespVO {
private String id;
/**
* 1:未签收
* 2:已签收
*/
private Integer status;
private String processName;
private String processKey;
private String businessKey;
private String formKey;
}

View File

@ -1,36 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.convert.form;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExcelVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormRespVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
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 WfFormConvert {
WfFormConvert INSTANCE = Mappers.getMapper(WfFormConvert.class);
WfForm convert(WfFormCreateReqVO bean);
WfForm convert(WfFormUpdateReqVO bean);
WfFormRespVO convert(WfForm bean);
List<WfFormRespVO> convertList(List<WfForm> list);
PageResult<WfFormRespVO> convertPage(PageResult<WfForm> page);
List<WfFormExcelVO> convertList02(List<WfForm> list);
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.convert.oa;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
/**
* 请假申请 Convert
*
* @author 芋艿
*/
@Mapper
public interface OaLeaveConvert {
OaLeaveConvert INSTANCE = Mappers.getMapper(OaLeaveConvert.class);
OaLeaveDO convert(OaLeaveCreateReqVO bean);
OaLeaveDO convert(OaLeaveUpdateReqVO bean);
OaLeaveRespVO convert(OaLeaveDO bean);
List<OaLeaveRespVO> convertList(List<OaLeaveDO> list);
PageResult<OaLeaveRespVO> convertPage(PageResult<OaLeaveDO> page);
List<OaLeaveExcelVO> convertList02(List<OaLeaveDO> list);
}

View File

@ -1,9 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.convert.workflow;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface TodoTaskConvert {
TodoTaskConvert INSTANCE = Mappers.getMapper(TodoTaskConvert.class);
}

View File

@ -1,55 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.List;
import java.util.Map;
/**
* 工作流的表单结果
* 用户每次填写工作流的申请表单时会保存一条记录到该表
*
* @author 芋道源码
*/
@TableName(value = "wf_form", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WfFormData extends BaseDO {
/**
* 编号
*/
private Long id;
/**
* 表单编号
*
* 关联 {@link WfForm#getId()}
*/
private Long formId;
/**
* 状态
*/
private Integer status;
/**
* 表单配置
*
* 冗余 {@link WfForm#getFields()}
* 主要考虑表单是可以修改的
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> fields;
/**
* 表单值
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> values;
}

View File

@ -1,60 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 请假申请 DO
*
* @author 芋艿
*/
@TableName("oa_leave")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OaLeaveDO extends BaseDO {
/**
* 请假表单主键
*/
@TableId
private Long id;
/**
* 流程id
*/
private String processInstanceId;
/**
* 状态
*/
private Integer status;
/**
* 申请人id
*/
private String userId;
/**
* 开始时间
*/
private Date startTime;
/**
* 结束时间
*/
private Date endTime;
/**
* 请假类型
*/
private String leaveType;
/**
* 原因
*/
private String reason;
/**
* 申请时间
*/
private Date applyTime;
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.process;
/**
* 流程模型实体类 映射 activiti ProcessDefinition接口
*
* @author ZJQ
* @date 2021/9/7 23:23
*/
public class ProcessDefinitionDO {
private String id;
private String category;
private String key;
private String name;
private String version;
private String resourceName;
private String deploymentId;
private String diagramResourceName;
private boolean suspended;
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.form;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
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;
import java.util.List;
/**
* 动态表单 Mapper
*
* @author 风里雾里
*/
@Mapper
public interface WfFormMapper extends BaseMapperX<WfForm> {
default PageResult<WfForm> selectPage(WfFormPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<WfForm>()
.likeIfPresent("name", reqVO.getName())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("form_json", reqVO.getFormJson())
.eqIfPresent("remark", reqVO.getRemark())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id") );
}
default List<WfForm> selectList(WfFormExportReqVO reqVO) {
return selectList(new QueryWrapperX<WfForm>()
.likeIfPresent("name", reqVO.getName())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("form_json", reqVO.getFormJson())
.eqIfPresent("remark", reqVO.getRemark())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id") );
}
}

View File

@ -1,46 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
/**
* 请假申请 Mapper
*
* @author 芋艿
*/
@Mapper
public interface OaLeaveMapper extends BaseMapperX<OaLeaveDO> {
default PageResult<OaLeaveDO> selectPage(OaLeavePageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<OaLeaveDO>()
.eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("user_id", reqVO.getUserId())
.betweenIfPresent("start_time", reqVO.getBeginStartTime(), reqVO.getEndStartTime())
.betweenIfPresent("end_time", reqVO.getBeginEndTime(), reqVO.getEndEndTime())
.eqIfPresent("leave_type", reqVO.getLeaveType())
.eqIfPresent("reason", reqVO.getReason())
.betweenIfPresent("apply_time", reqVO.getBeginApplyTime(), reqVO.getEndApplyTime())
.orderByDesc("id") );
}
default List<OaLeaveDO> selectList(OaLeaveExportReqVO reqVO) {
return selectList(new QueryWrapperX<OaLeaveDO>()
.eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("user_id", reqVO.getUserId())
.betweenIfPresent("start_time", reqVO.getBeginStartTime(), reqVO.getEndStartTime())
.betweenIfPresent("end_time", reqVO.getBeginEndTime(), reqVO.getEndEndTime())
.eqIfPresent("leave_type", reqVO.getLeaveType())
.eqIfPresent("reason", reqVO.getReason())
.betweenIfPresent("apply_time", reqVO.getBeginApplyTime(), reqVO.getEndApplyTime())
.orderByDesc("id") );
}
}

View File

@ -1,13 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* activiti 系统 错误码枚举类
*
* 003 activiti
* 001 oa
* activiti 系统使用 1-003-000-000
*/
public interface OaErrorCodeConstants {
ErrorCode LEAVE_NOT_EXISTS = new ErrorCode(1003001001, "请假申请不存在");
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.enums.form;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* activiti 系统 错误码枚举类
*
* 003 activiti
* 001 oa
* activiti 系统使用 1-003-000-000
*/
public interface WfFormErrorCodeConstants {
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1003001002, "动态表单不存在");
}

View File

@ -1,2 +0,0 @@
// TODO @芋艿思考下 activitioa 的定位边界模块的拆分
package cn.iocoder.yudao.adminserver.modules.activiti;

View File

@ -1,62 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
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 cn.iocoder.yudao.framework.security.core.LoginUser;
import org.activiti.api.runtime.shared.identity.UserGroupManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Collections.singleton;
@Service
public class UserGroupManagerService implements UserGroupManager {
@Resource
private UserDetailsService userDetailsService;
@Resource
private SysUserService userService;
@Resource
private SysPostService sysPostService;
/**
* 暂时使用岗位来代替
* @param userId
* @return
*/
@Override
public List<String> getUserGroups(String userId) {
// final LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(userId);
// final Long id = loginUser.getId();
final SysUserDO user = userService.getUserByUsername(userId);
return sysPostService.getPosts(user.getPostIds()).stream().map(post -> post.getCode()).collect(Collectors.toList());
}
@Override
public List<String> getUserRoles(String userId) {
return Arrays.asList("ROLE_ACTIVITI_USER");
}
@Override
public List<String> getGroups() {
throw new UnsupportedOperationException("getGroups is now un supported");
}
@Override
public List<String> getUsers() {
throw new UnsupportedOperationException("getGroups is now un supported");
}
}

View File

@ -1,31 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import org.activiti.api.runtime.shared.security.PrincipalGroupsProvider;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
@Service
public class UserGroupsProvider implements PrincipalGroupsProvider {
@Override
public List<String> getGroups(Principal principal) {
if(principal instanceof Authentication){
Authentication authentication = (Authentication) principal;
final Object user = authentication.getPrincipal();
if( user instanceof LoginUser){
return ((LoginUser) user).getGroups();
}else{
return Collections.emptyList();
}
}else{
return Collections.emptyList();
}
}
}

View File

@ -1,75 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.form;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import java.util.*;
import javax.validation.*;
/**
* 动态表单 Service 接口
*
* TODO @风里雾里
*/
public interface WfFormService {
/**
* 创建动态表单
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createForm(@Valid WfFormCreateReqVO createReqVO);
/**
* 更新动态表单
*
* @param updateReqVO 更新信息
*/
void updateForm(@Valid WfFormUpdateReqVO updateReqVO);
/**
* 删除动态表单
*
* @param id 编号
*/
void deleteForm(Long id);
/**
* 获得动态表单
*
* @param id 编号
* @return 动态表单
*/
WfForm getForm(Long id);
/**
* 获得动态表单列表
*
* @param ids 编号
* @return 动态表单列表
*/
List<WfForm> getFormList(Collection<Long> ids);
/**
* 获得动态表单分页
*
* @param pageReqVO 分页查询
* @return 动态表单分页
*/
PageResult<WfForm> getFormPage(WfFormPageReqVO pageReqVO);
/**
* 获得动态表单列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 动态表单列表
*/
List<WfForm> getFormList(WfFormExportReqVO exportReqVO);
}

View File

@ -1,86 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.form.impl;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.convert.form.WfFormConvert;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.form.WfFormMapper;
import cn.iocoder.yudao.adminserver.modules.activiti.service.form.WfFormService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.adminserver.modules.activiti.enums.form.WfFormErrorCodeConstants.FORM_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 动态表单 Service 实现类
*
* TODO @风里雾里
*/
@Service
@Validated
public class WfFormServiceImpl implements WfFormService {
@Resource
private WfFormMapper formMapper;
@Override
public Long createForm(WfFormCreateReqVO createReqVO) {
// 插入
WfForm form = WfFormConvert.INSTANCE.convert(createReqVO);
formMapper.insert(form);
// 返回
return form.getId();
}
@Override
public void updateForm(WfFormUpdateReqVO updateReqVO) {
// 校验存在
this.validateFormExists(updateReqVO.getId());
// 更新
WfForm updateObj = WfFormConvert.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 WfForm getForm(Long id) {
return formMapper.selectById(id);
}
@Override
public List<WfForm> getFormList(Collection<Long> ids) {
return formMapper.selectBatchIds(ids);
}
@Override
public PageResult<WfForm> getFormPage(WfFormPageReqVO pageReqVO) {
return formMapper.selectPage(pageReqVO);
}
@Override
public List<WfForm> getFormList(WfFormExportReqVO exportReqVO) {
return formMapper.selectList(exportReqVO);
}
}

View File

@ -1,76 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveExportReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeavePageReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 请假申请 Service 接口
*
* @author 芋艿
*/
public interface OaLeaveService {
/**
* 创建请假申请
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createLeave(@Valid OaLeaveCreateReqVO createReqVO);
/**
* 更新请假申请
*
* @param updateReqVO 更新信息
*/
void updateLeave(@Valid OaLeaveUpdateReqVO updateReqVO);
/**
* 删除请假申请
*
* @param id 编号
*/
void deleteLeave(Long id);
/**
* 获得请假申请
*
* @param id 编号
* @return 请假申请
*/
OaLeaveDO getLeave(Long id);
/**
* 获得请假申请列表
*
* @param ids 编号
* @return 请假申请列表
*/
List<OaLeaveDO> getLeaveList(Collection<Long> ids);
/**
* 获得请假申请分页
*
* @param pageReqVO 分页查询
* @return 请假申请分页
*/
PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO);
/**
* 获得请假申请列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 请假申请列表
*/
List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO);
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Component
public class ReportBackEndProcessor implements ExecutionListener {
@Resource
private OaLeaveMapper leaveMapper;
// @Override
// @Transactional(rollbackFor = Exception.class)
// public void notify(DelegateTask delegateTask) {
// final String businessKey = delegateTask.getExecution().getProcessInstanceBusinessKey();
// UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
// updateWrapper.eq("id", Long.valueOf(businessKey));
// OaLeaveDO updateDo = new OaLeaveDO();
// updateDo.setStatus(2);
// leaveMapper.update(updateDo, updateWrapper);
// }
@Override
@Transactional(rollbackFor = Exception.class)
public void notify(DelegateExecution delegateExecution) {
final String businessKey = delegateExecution.getProcessInstanceBusinessKey();
// TODO @jsonservice 不要出现 dao 的元素例如说 UpdateWrapper这里我们可以调用 updateById 方法
UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", Long.valueOf(businessKey));
OaLeaveDO updateDo = new OaLeaveDO();
updateDo.setStatus(2); // TODO @jsonstatus 要枚举起来不要出现 magic number
leaveMapper.update(updateDo, updateWrapper);
}
}

View File

@ -1,141 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.oa.impl;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveExportReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeavePageReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.activiti.enums.OaErrorCodeConstants.LEAVE_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 请假申请 Service 实现类
*
* @author 芋艿
*/
@Service
@Validated
public class OaLeaveServiceImpl implements OaLeaveService {
@Resource
private OaLeaveMapper leaveMapper;
@Resource
private RuntimeService runtimeService;
@Resource
private org.activiti.engine.TaskService activitiTaskService;
@Resource
private TaskRuntime taskRuntime;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createLeave(OaLeaveCreateReqVO createReqVO) {
// 插入 OA 请假单
OaLeaveDO leave = OaLeaveConvert.INSTANCE.convert(createReqVO);
leave.setStatus(1);
leave.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
leaveMapper.insert(leave);
// 创建工作流
Map<String, Object> variables = new HashMap<>();
// 如何得到部门领导人暂时写死
variables.put("deptLeader", "admin"); // TODO @芋艿需要部门的负责人
Long id = leave.getId();
String businessKey = String.valueOf(id);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(createReqVO.getProcessKey(), businessKey, variables);
String processInstanceId = processInstance.getProcessInstanceId();
// TODO @jsonservice 不要出现 dao 的元素例如说 UpdateWrapper这里我们可以调用 updateById 方法
// 将工作流的编号更新到 OA 请假单中
UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", id);
OaLeaveDO updateDo = new OaLeaveDO();
updateDo.setProcessInstanceId(processInstanceId);
leaveMapper.update(updateDo, updateWrapper);
return id;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateLeave(OaLeaveUpdateReqVO updateReqVO) {
// 校验存在
this.validateLeaveExists(updateReqVO.getId());
final Task task = taskRuntime.task(updateReqVO.getTaskId());
activitiTaskService.addComment(task.getId(), task.getProcessInstanceId(), updateReqVO.getComment());
Map<String, Object> variables = updateReqVO.getVariables();
//如何得到部门领导人 暂时写死
variables.put("deptLeader", "admin");
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId())
.withVariables(variables)
.build());
// TODO @jason不需要加 final 虽然是不变但是代码比较少这么去写
final Object reApply = variables.get("reApply");
// TODO @jason直接使用 Objects.equals(reApply, true) 就可以
if((reApply instanceof Boolean) && (Boolean)reApply){
// 更新 表单
OaLeaveDO updateObj = OaLeaveConvert.INSTANCE.convert(updateReqVO);
leaveMapper.updateById(updateObj);
}
}
@Override
public void deleteLeave(Long id) {
// 校验存在
this.validateLeaveExists(id);
// 删除
leaveMapper.deleteById(id);
// TODO @jason需要调用 runtimeService delete 方法删除
}
private void validateLeaveExists(Long id) {
if (leaveMapper.selectById(id) == null) {
throw exception(LEAVE_NOT_EXISTS);
}
}
@Override
public OaLeaveDO getLeave(Long id) {
return leaveMapper.selectById(id);
}
@Override
public List<OaLeaveDO> getLeaveList(Collection<Long> ids) {
return leaveMapper.selectBatchIds(ids);
}
@Override
public PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO) {
return leaveMapper.selectPage(pageReqVO);
}
@Override
public List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO) {
return leaveMapper.selectList(exportReqVO);
}
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.process;
import org.springframework.web.multipart.MultipartFile;
/**
* 流程基础管理
*
* @author ZJQ
* @date 2021/9/5 21:00
*/
public interface ProcessService {
/**
* 上传流程文件进行流程模型部署
* @param multipartFile 上传文件
*/
void deployProcess(MultipartFile multipartFile);
/**
* 激活或者挂起流程模型实体
* @param processDefinitionId 流程模型实体id
* @param type 类型
* @return 状态
*/
String setActivOrHang(String processDefinitionId,String type);
}

View File

@ -1,109 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.process.impl;
import cn.iocoder.yudao.adminserver.modules.activiti.service.process.ProcessService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.FILE_UPLOAD_FAILED;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 流程基础管理
*
* @author ZJQ
* @date 2021/9/5 21:04
*/
@Service
@Slf4j
public class ProcessServiceImpl implements ProcessService {
private static final String BPMN20_XML = "bpmn20.xml";
@Resource
private RepositoryService repositoryService;
/**
* 上传流程文件进行流程部署
* @param multipartFile 上传文件
*/
@Override
public void deployProcess(MultipartFile multipartFile) {
String fileName = multipartFile.getOriginalFilename();
try (InputStream inputStream = multipartFile.getInputStream()){
Deployment deployment = getDeplymentByType(inputStream,fileName);
//获取部署成功的流程模型
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
processDefinitions.forEach((processDefinition)->{
//设置线上部署流程模型名字
String proDefId = processDefinition.getId();
repositoryService.setProcessDefinitionCategory(proDefId,fileName);
log.info("流程文件部署成功流程ID="+proDefId);
});
} catch (IOException e) {
log.error("流程部署出现异常"+e);
}
}
/**
* 激活或者挂起流程模型实体
* @param processDefinitionId 流程模型实体id
* @param type 类型
* @return 提示
*/
@Override
public String setActivOrHang(String processDefinitionId, String type) {
String result = "无操作";
switch (type){
case "active":
repositoryService.activateProcessDefinitionById(processDefinitionId,true,null);
result = "已激活ID为【"+processDefinitionId+"】的流程模型实例";
break;
case "suspend":
repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);
result = "已挂起ID为【"+processDefinitionId+"】的流程模型实例";
break;
default:
break;
}
return result;
}
/**
* 根据上传文件类型对应实现不同方式的流程部署
* @param inputStream 文件输入流
* @param fileName 文件名
* @return 文件部署流程
*/
public Deployment getDeplymentByType(InputStream inputStream,String fileName){
Deployment deployment;
String type = FilenameUtils.getExtension(fileName);
switch (type){
case "bpmn":
String baseName = FilenameUtils.getBaseName(fileName);
deployment = repositoryService.createDeployment().addInputStream(baseName+"."+BPMN20_XML,inputStream).deploy();
break;
case "png":
deployment = repositoryService.createDeployment().addInputStream(fileName,inputStream).deploy();
break;
case "zip":
case "bar":
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();
break;
default:
throw exception(FILE_UPLOAD_FAILED);
}
return deployment;
}
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import java.util.List;
// TODO @芋艿前缀注释
public interface TaskService {
PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO);
void claimTask(String taskId);
void getTaskHistory(String taskId);
void completeTask(TaskReqVO taskReq);
// void flowImage(String taskId, HttpServletResponse response);
TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery);
List<TaskStepVO> getHistorySteps(String processInstanceId);
TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery);
}

View File

@ -1,266 +0,0 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.impl;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.google.common.collect.ImmutableMap;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class TaskServiceImpl implements TaskService {
@Resource
private TaskRuntime taskRuntime;
@Resource
private org.activiti.engine.TaskService activitiTaskService;
@Resource
private HistoryService historyService;
@Resource
private RepositoryService repositoryService;
@Resource
private OaLeaveMapper leaveMapper;
private static Map<String,String> taskVariable = ImmutableMap.<String,String>builder()
.put("deptLeaderVerify","deptLeaderApproved")
.put("hrVerify","hrApproved")
.build();
public TaskServiceImpl() {
}
@Override
public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
final LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// TODO @jason封装一个方法用于转换成 activiti 的分页对象
final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
Page<Task> pageTasks = taskRuntime.tasks(pageable);
// TODO @jasonconvert 里转换
List<Task> tasks = pageTasks.getContent();
int totalItems = pageTasks.getTotalItems();
final List<TodoTaskRespVO> respVOList = tasks.stream().map(task -> {
TodoTaskRespVO respVO = new TodoTaskRespVO();
respVO.setId(task.getId());
final ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
respVO.setProcessName(definition.getName());
respVO.setProcessKey(definition.getKey());
respVO.setBusinessKey(task.getBusinessKey());
respVO.setStatus(task.getAssignee() == null ? 1 : 2);
return respVO;
}).collect(Collectors.toList());
// TODO @jason要注意泛型哈
return new PageResult(respVOList, Long.valueOf(totalItems)); // TODO @jason(long) 转换即可
}
@Override
public void claimTask(String taskId) {
taskRuntime.claim(new ClaimTaskPayloadBuilder()
.withTaskId(taskId)
.withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername())
.build());
}
@Override
public void getTaskHistory(String taskId) {
final List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().
processInstanceId("8e2801fc-1a38-11ec-98ce-74867a13730f").list();
}
// TODO @jason一个方法里会有多个方法的调用最好写下对应的注释这样容易理解
@Override
@Transactional
public void completeTask(TaskReqVO taskReq) {
final Task task = taskRuntime.task(taskReq.getTaskId());
final Map<String, Object> variables = taskReq.getVariables();
activitiTaskService.addComment(taskReq.getTaskId(), task.getProcessInstanceId(), taskReq.getComment());
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskReq.getTaskId())
.withVariables(taskReq.getVariables())
.build());
// if(variables.containsValue(Boolean.FALSE)){
// final String businessKey = task.getBusinessKey();
// UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
// updateWrapper.eq("id", Long.valueOf(businessKey));
// OaLeaveDO updateDo = new OaLeaveDO();
// updateDo.setStatus(2);
// leaveMapper.update(updateDo, updateWrapper);
// }
}
// @Override
// public void flowImage(String taskId, HttpServletResponse response) {
//
// final Task task = taskRuntime.task(taskId);
// BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
// final Process process = bpmnModel.getMainProcess();
// ProcessDefinitionEntity processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
// List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
// List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstance.getId());
// ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
// InputStream imageStream =diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds, highLightedFlows);
//
// // 输出资源内容到相应对象
// byte[] b = new byte[1024];
// int len;
// while ((len = imageStream.read(b, 0, 1024)) != -1) {
// response.getOutputStream().write(b, 0, len);
// }
// }
@Override
public TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery) {
TaskHandleVO handleVO = new TaskHandleVO();
// String processKey = taskQuery.getProcessKey();
// if ("leave".equals(processKey)) {
// String businessKey = taskQuery.getBusinessKey();
// final OaLeaveDO leave = leaveMapper.selectById(Long.valueOf(businessKey));
// handleVO.setFormObject( OaLeaveConvert.INSTANCE.convert(leave));
// }
//
// final String taskDefKey = task.getTaskDefinitionKey();
// final String variableName = Optional.ofNullable(taskVariable.get(taskDefKey)).orElse("");
// handleVO.setTaskVariable(variableName);
final Task task = taskRuntime.task(taskQuery.getTaskId());
List<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId());
handleVO.setHistoryTask(steps);
return handleVO;
}
private List<TaskStepVO> getTaskSteps(String processInstanceId) {
// 获得已完成的活动
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.finished()
.orderByHistoricActivityInstanceStartTime().asc().list();
// 获得对应的步骤
List<TaskStepVO> steps = new ArrayList<>();
finished.forEach(instance -> {
// TODO @jason放到 convert
TaskStepVO step = new TaskStepVO();
step.setStepName(instance.getActivityName());
step.setStartTime(instance.getStartTime());
step.setEndTime(instance.getEndTime());
step.setAssignee(instance.getAssignee());
step.setStatus(1);
// TODO @jason一般判数组为空使用 CollUtil.isEmpty 会好点哈另外null 时候不用填写 "" 的哈
List<Comment> comments = activitiTaskService.getTaskComments(instance.getTaskId());
if (comments.size() > 0) {
step.setComment(comments.get(0).getFullMessage());
} else {
step.setComment("");
}
steps.add(step);
});
// 获得未完成的活动
List<HistoricActivityInstance> unfinished = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.unfinished().list();
// 获得对应的步骤
// TODO @json其实已完成和未完成它们的 convert 的逻辑是一致的
for (HistoricActivityInstance instance : unfinished) {
TaskStepVO step = new TaskStepVO();
step.setStepName(instance.getActivityName());
step.setStartTime(instance.getStartTime());
step.setEndTime(instance.getEndTime());
step.setAssignee(Optional.ofNullable(instance.getAssignee()).orElse(""));
step.setComment("");
step.setStatus(0);
steps.add(step);
}
return steps;
}
@Override
public List<TaskStepVO> getHistorySteps(String processInstanceId) {
return getTaskSteps(processInstanceId);
}
@Override
public TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery) {
final Task task = taskRuntime.task(taskQuery.getTaskId());
// 转换结果
TodoTaskRespVO respVO = new TodoTaskRespVO();
respVO.setFormKey(task.getFormKey());
respVO.setBusinessKey(task.getBusinessKey());
respVO.setId(task.getId());
return respVO;
}
// private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
//
// List<String> highLightedFlows = new ArrayList<String>();
// List<HistoricActivityInstance> historicActivityInstances = historyService
// .createHistoricActivityInstanceQuery()
// .processInstanceId(processInstanceId)
// .orderByHistoricActivityInstanceStartTime().asc().list();
//
// List<String> historicActivityInstanceList = new ArrayList<String>();
// for (HistoricActivityInstance hai : historicActivityInstances) {
// historicActivityInstanceList.add(hai.getActivityId());
// }
// // add current activities to list
// List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
// historicActivityInstanceList.addAll(highLightedActivities);
// activities and their sequence-flows
// for (ActivityImpl activity : processDefinition.getActivities()) {
// int index = historicActivityInstanceList.indexOf(activity.getId());
//
// if (index >= 0 && index + 1 < historicActivityInstanceList.size()) {
// List<PvmTransition> pvmTransitionList = activity
// .getOutgoingTransitions();
// for (PvmTransition pvmTransition : pvmTransitionList) {
// String destinationFlowId = pvmTransition.getDestination().getId();
// if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1))) {
// highLightedFlows.add(pvmTransition.getId());
// }
// }
// }
// }
// return highLightedFlows;
// }
}

View File

@ -0,0 +1,79 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.*;
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.service.definition.BpmFormService;
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 java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "动态表单")
@RestController
@RequestMapping("/bpm/form")
@Validated
public class BpmFormController {
@Resource
private BpmFormService formService;
@PostMapping("/create")
@ApiOperation("创建动态表单")
@PreAuthorize("@ss.hasPermission('bpm:form:create')")
public CommonResult<Long> createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) {
return success(formService.createForm(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新动态表单")
@PreAuthorize("@ss.hasPermission('bpm:form:update')")
public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) {
formService.updateForm(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除动态表单")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('bpm:form:delete')")
public CommonResult<Boolean> deleteForm(@RequestParam("id") Long id) {
formService.deleteForm(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得动态表单")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('bpm:form:query')")
public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) {
BpmFormDO form = formService.getForm(id);
return success(BpmFormConvert.INSTANCE.convert(form));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获得动态表单的精简列表", notes = "用于表单下拉框")
public CommonResult<List<BpmFormSimpleRespVO>> getSimpleForms() {
List<BpmFormDO> list = formService.getFormList();
return success(BpmFormConvert.INSTANCE.convertList2(list));
}
@GetMapping("/page")
@ApiOperation("获得动态表单分页")
@PreAuthorize("@ss.hasPermission('bpm:form:query')")
public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) {
PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO);
return success(BpmFormConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@ -0,0 +1,97 @@
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);
}
}

View File

@ -0,0 +1,4 @@
### 请求 /bpm/process-definition/list 接口 => 成功
GET {{baseUrl}}/bpm/process-definition/list?suspensionState=1
tenant-id: 1
Authorization: Bearer {{token}}

View File

@ -0,0 +1,60 @@
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);
}
}

View File

@ -0,0 +1,4 @@
### 请求 /bpm/task-assign-rule/list 接口 => 成功
GET {{baseUrl}}/bpm/task-assign-rule/list?processDefinitionId=leave:9:59689ba0-7284-11ec-965c-a2380e71991a
tenant-id: 1
Authorization: Bearer {{token}}

View File

@ -0,0 +1,59 @@
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);
}
}

View File

@ -0,0 +1,89 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
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.BpmUserGroupRespVO;
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.service.definition.BpmUserGroupService;
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserSimpleRespVO;
import cn.iocoder.yudao.adminserver.modules.system.convert.user.SysUserConvert;
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.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 java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "用户组")
@RestController
@RequestMapping("/bpm/user-group")
@Validated
public class BpmUserGroupController {
@Resource
private BpmUserGroupService userGroupService;
@PostMapping("/create")
@ApiOperation("创建用户组")
@PreAuthorize("@ss.hasPermission('bpm:user-group:create')")
public CommonResult<Long> createUserGroup(@Valid @RequestBody BpmUserGroupCreateReqVO createReqVO) {
return success(userGroupService.createUserGroup(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新用户组")
@PreAuthorize("@ss.hasPermission('bpm:user-group:update')")
public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody BpmUserGroupUpdateReqVO updateReqVO) {
userGroupService.updateUserGroup(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除用户组")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('bpm:user-group:delete')")
public CommonResult<Boolean> deleteUserGroup(@RequestParam("id") Long id) {
userGroupService.deleteUserGroup(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得用户组")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
public CommonResult<BpmUserGroupRespVO> getUserGroup(@RequestParam("id") Long id) {
BpmUserGroupDO userGroup = userGroupService.getUserGroup(id);
return success(BpmUserGroupConvert.INSTANCE.convert(userGroup));
}
@GetMapping("/page")
@ApiOperation("获得用户组分页")
@PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
public CommonResult<PageResult<BpmUserGroupRespVO>> getUserGroupPage(@Valid BpmUserGroupPageReqVO pageVO) {
PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(pageVO);
return success(BpmUserGroupConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获取用户组精简信息列表", notes = "只包含被开启的用户组,主要用于前端的下拉选项")
public CommonResult<List<BpmUserGroupRespVO>> getSimpleUserGroups() {
// 获用户门列表只要开启状态的
List<BpmUserGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 排序后返回给前端
return success(BpmUserGroupConvert.INSTANCE.convertList2(list));
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 动态表单 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmFormBaseVO {
@ApiModelProperty(value = "表单名称", required = true, example = "芋道")
@NotNull(message = "表单名称不能为空")
private String name;
@ApiModelProperty(value = "表单状态", required = true, notes = "参见 CommonStatusEnum 枚举", example = "1")
@NotNull(message = "表单状态不能为空")
private Integer status;
@ApiModelProperty(value = "备注", example = "我是备注")
private String remark;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("动态表单创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormCreateReqVO extends BpmFormBaseVO {
@ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
@NotNull(message = "表单的配置不能为空")
private String conf;
@ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
@NotNull(message = "表单项的数组不能为空")
private List<String> fields;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
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 BpmFormPageReqVO extends PageParam {
@ApiModelProperty(value = "表单名称", example = "芋道")
private String name;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
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;
import java.util.List;
@ApiModel("动态表单 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormRespVO extends BpmFormBaseVO {
@ApiModelProperty(value = "表单编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
@NotNull(message = "表单的配置不能为空")
private String conf;
@ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
@NotNull(message = "表单项的数组不能为空")
private List<String> fields;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -0,0 +1,17 @@
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;
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import java.util.List;
@ApiModel("动态表单更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormUpdateReqVO extends BpmFormBaseVO {
@ApiModelProperty(value = "表单编号", required = true, example = "1024")
@NotNull(message = "表单编号不能为空")
private Long id;
@ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
@NotNull(message = "表单的配置不能为空")
private String conf;
@ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
@NotNull(message = "表单项的数组不能为空")
private List<String> fields;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 用户组 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmUserGroupBaseVO {
@ApiModelProperty(value = "组名", required = true, example = "芋道")
@NotNull(message = "组名不能为空")
private String name;
@ApiModelProperty(value = "描述", required = true, example = "芋道源码")
@NotNull(message = "描述不能为空")
private String description;
@ApiModelProperty(value = "成员编号数组", required = true, example = "1,2,3")
@NotNull(message = "成员编号数组不能为空")
private Set<Long> memberUserIds;
@ApiModelProperty(value = "状态", required = true, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@ -0,0 +1,14 @@
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 {
}

View File

@ -1,30 +1,25 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
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")
@ApiModel("用户组分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WfFormPageReqVO extends PageParam {
public class BpmUserGroupPageReqVO extends PageParam {
@ApiModelProperty(value = "表单名称")
@ApiModelProperty(value = "组名", example = "芋道")
private String name;
@ApiModelProperty(value = "商户状态")
@ApiModelProperty(value = "状态", example = "1")
private Integer status;
@ApiModelProperty(value = "表单JSON")
private String formJson;
@ApiModelProperty(value = "备注")
private String remark;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;

View File

@ -1,16 +1,16 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("动态表单 Response VO")
@ApiModel("用户组 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WfFormRespVO extends WfFormBaseVO {
public class BpmUserGroupRespVO extends BpmUserGroupBaseVO {
@ApiModelProperty(value = "表单编号", required = true)
@ApiModelProperty(value = "编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiModel("用户组精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BpmUserGroupSimpleRespVO {
@ApiModelProperty(value = "用户组编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "用户组名字", required = true, example = "芋道")
private String name;
}

View File

@ -0,0 +1,18 @@
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;
}

View File

@ -0,0 +1,22 @@
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;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
/**
* 流程模型 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmModelBaseVO {
@ApiModelProperty(value = "流程标识", required = true, example = "process_yudao")
@NotEmpty(message = "流程标识不能为空")
private String key;
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
@NotEmpty(message = "流程名称不能为空")
private String name;
@ApiModelProperty(value = "流程描述", example = "我是描述")
private String description;
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
@NotEmpty(message = "流程分类不能为空")
private String category;
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
private Integer formType;
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private Long formId;
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomCreatePath;
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomViewPath;
}

View File

@ -0,0 +1,26 @@
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 javax.validation.constraints.NotEmpty;
@ApiModel("流程模型的创建 Request VO")
@Data
public class BpmModelCreateReqVO {
@ApiModelProperty(value = "流程标识", required = true, example = "process_yudao")
@NotEmpty(message = "流程标识不能为空")
private String key;
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
@NotEmpty(message = "流程名称不能为空")
private String name;
@ApiModelProperty(value = "流程描述", example = "我是描述")
private String description;
}

View File

@ -0,0 +1,49 @@
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 java.util.Date;
@ApiModel("流程模型的分页的每一项 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmModelPageItemRespVO extends BpmModelBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "表单名字", example = "请假表单")
private String formName;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
/**
* 最新部署的流程定义
*/
private ProcessDefinition processDefinition;
@ApiModel("流程定义")
@Data
public static class ProcessDefinition {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "版本", required = true, example = "1")
private Integer version;
@ApiModelProperty(value = "部署时间", required = true)
private Date deploymentTime;
@ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举")
private Integer suspensionState;
}
}

View File

@ -0,0 +1,26 @@
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 java.util.Date;
@ApiModel("流程模型的创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmModelRespVO extends BpmModelBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "BPMN XML", required = true)
private String bpmnXml;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -0,0 +1,40 @@
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 javax.validation.constraints.NotEmpty;
@ApiModel("流程模型的更新 Request VO")
@Data
public class BpmModelUpdateReqVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
@NotEmpty(message = "编号不能为空")
private String id;
@ApiModelProperty(value = "流程名称", example = "芋道")
private String name;
@ApiModelProperty(value = "流程描述", example = "我是描述")
private String description;
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
private String category;
@ApiModelProperty(value = "BPMN XML", required = true)
private String bpmnXml;
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
private Integer formType;
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private Long formId;
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomCreatePath;
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomViewPath;
}

View File

@ -0,0 +1,21 @@
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 javax.validation.constraints.NotNull;
@ApiModel("流程模型更新状态 Request VO")
@Data
public class BpmModelUpdateStateReqVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
@NotNull(message = "编号不能为空")
private String id;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SuspensionState 枚举")
@NotNull(message = "状态不能为空")
private Integer state;
}

View File

@ -0,0 +1,26 @@
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;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
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;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel("流程定义列表 Request VO")
public class BpmProcessDefinitionListReqVO extends PageParam {
@ApiModelProperty(value = "中断状态", example = "1", notes = "参见 SuspensionState 枚举")
private Integer suspensionState;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("流程定义的分页的每一项 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO {
@ApiModelProperty(value = "表单名字", example = "请假表单")
private String formName;
@ApiModelProperty(value = "部署时间", required = true)
private Date deploymentTime;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
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;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel("流程定义分页 Request VO")
public class BpmProcessDefinitionPageReqVO extends PageParam {
@ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配")
private String key;
}

View File

@ -0,0 +1,52 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("流程定义 Response VO")
@Data
public class BpmProcessDefinitionRespVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "版本", required = true, example = "1")
private Integer version;
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
@NotEmpty(message = "流程名称不能为空")
private String name;
@ApiModelProperty(value = "流程描述", example = "我是描述")
private String description;
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
@NotEmpty(message = "流程分类不能为空")
private String category;
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
private Integer formType;
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private Long formId;
@ApiModelProperty(value = "表单的配置", required = true,
notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formConf;
@ApiModelProperty(value = "表单项的数组", required = true,
notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private List<String> formFields;
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomCreatePath;
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomViewPath;
@ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举")
private Integer suspensionState;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* 流程任务分配规则 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmTaskAssignRuleBaseVO {
@ApiModelProperty(value = "规则类型", required = true, example = "bpm_task_assign_rule_type")
@NotNull(message = "规则类型不能为空")
private Integer type;
@ApiModelProperty(value = "规则值数组", required = true, example = "1,2,3")
@NotNull(message = "规则值数组不能为空")
private Set<Long> options;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotEmpty;
@ApiModel("流程任务分配规则的创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO {
@ApiModelProperty(value = "流程模型的编号", required = true, example = "1024")
@NotEmpty(message = "流程模型的编号不能为空")
private String modelId;
@ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048")
@NotEmpty(message = "流程任务定义的编号不能为空")
private String taskDefinitionKey;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ApiModel("流程任务分配规则的 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO {
@ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "流程模型的编号", required = true, example = "2048")
private String modelId;
@ApiModelProperty(value = "流程定义的编号", required = true, example = "4096")
private String processDefinitionId;
@ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048")
private String taskDefinitionKey;
@ApiModelProperty(value = "流程任务定义的名字", required = true, example = "关注芋道")
private String taskDefinitionName;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
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.Set;
@ApiModel("流程任务分配规则的更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO {
@ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024")
@NotNull(message = "任务分配规则的编号不能为空")
private Long id;
}

View File

@ -0,0 +1,12 @@
### 请求 /bpm/oa/leave/create 接口 => 成功
POST {{baseUrl}}/bpm/oa/leave/create
Content-Type: application/json
tenant-id: 1
Authorization: Bearer {{token}}
{
"startTime": "2022-03-01",
"endTime": "2022-03-05",
"type": 1,
"reason": "我要请假啦啦啦!"
}

View File

@ -0,0 +1,63 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.BpmOALeaveCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.BpmOALeavePageReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.BpmOALeaveRespVO;
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.service.oa.BpmOALeaveService;
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;
/**
* OA 请假申请 Controller用于演示自己存储数据接入工作流的例子
*
* @author jason
* @author 芋道源码
*/
@Api(tags = "OA 请假申请")
@RestController
@RequestMapping("/bpm/oa/leave")
@Validated
public class BpmOALeaveController {
@Resource
private BpmOALeaveService leaveService;
@PostMapping("/create")
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:create')")
@ApiOperation("创建请求申请")
public CommonResult<Long> createLeave(@Valid @RequestBody BpmOALeaveCreateReqVO createReqVO) {
return success(leaveService.createLeave(getLoginUserId(), createReqVO));
}
@GetMapping("/get")
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
@ApiOperation("获得请假申请")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
public CommonResult<BpmOALeaveRespVO> getLeave(@RequestParam("id") Long id) {
BpmOALeaveDO leave = leaveService.getLeave(id);
return success(BpmOALeaveConvert.INSTANCE.convert(leave));
}
@GetMapping("/page")
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
@ApiOperation("获得请假申请分页")
public CommonResult<PageResult<BpmOALeaveRespVO>> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) {
PageResult<BpmOALeaveDO> pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO);
return success(BpmOALeaveConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 请假申请 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmOALeaveBaseVO {
@ApiModelProperty(value = "请假的开始时间", required = true)
@NotNull(message = "开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date startTime;
@ApiModelProperty(value = "请假的结束时间", required = true)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "请假类型", required = true, example = "1", notes = "参见 bpm_oa_type 枚举")
private Integer type;
@ApiModelProperty(value = "原因", required = true, example = "阅读芋道源码")
private String reason;
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.AssertTrue;
@ApiModel("请假申请创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOALeaveCreateReqVO extends BpmOALeaveBaseVO {
@AssertTrue(message = "结束时间,需要在开始时间之后")
public boolean isEndTimeValid() {
return !getEndTime().before(getStartTime());
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
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 BpmOALeavePageReqVO extends PageParam {
@ApiModelProperty(value = "状态", example = "1", notes = "参见 bpm_process_instance_result 枚举")
private Integer result;
@ApiModelProperty(value = "请假类型", example = "1", notes = "参见 bpm_oa_type")
private Integer type;
@ApiModelProperty(value = "原因", example = "阅读芋道源码", notes = "模糊匹配")
private String reason;
@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;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
import lombok.*;
import io.swagger.annotations.*;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("请假申请 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOALeaveRespVO extends BpmOALeaveBaseVO {
@ApiModelProperty(value = "请假表单主键", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 bpm_process_instance_result 枚举")
private Integer result;
@ApiModelProperty(value = "申请时间", required = true)
@NotNull(message = "申请时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date createTime;
@ApiModelProperty(value = "流程id")
private String processInstanceId;
}

View File

@ -0,0 +1,55 @@
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);
}
}

View File

@ -0,0 +1,29 @@
### 请求 /bpm/process-instance/create 接口 => 成功
POST {{baseUrl}}/bpm/process-instance/create
Content-Type: application/json
tenant-id: 1
Authorization: Bearer {{token}}
{
"processDefinitionId": "gateway_test:2:00e52d8e-701b-11ec-aca9-a2380e71991a",
"variables": {
"a": 1,
"b": "2"
}
}
### 请求 /bpm/process-instance/cancel 接口 => 成功
DELETE {{baseUrl}}/bpm/process-instance/cancel
Content-Type: application/json
tenant-id: 1
Authorization: Bearer {{token}}
{
"id": "b9220387-7088-11ec-bcae-a2380e71991a",
"reason": "我就取消"
}
### 请求 /bpm/process-instance/get 接口 => 成功
GET {{baseUrl}}/bpm/process-instance/get?id=537cceb3-768c-11ec-afcd-a2380e71991a
tenant-id: 1
Authorization: Bearer {{token}}

View File

@ -0,0 +1,60 @@
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));
}
}

View File

@ -0,0 +1,14 @@
### 请求 /bpm/task/todo-page 接口 => 成功
GET {{baseUrl}}/bpm/task/todo-page
tenant-id: 1
Authorization: Bearer {{token}}
### 请求 /bpm/task/done-page 接口 => 成功
GET {{baseUrl}}/bpm/task/done-page?pageSize=100
tenant-id: 1
Authorization: Bearer {{token}}
### 请求 /bpm/task/list-by-process-instance-id 接口 => 成功
GET {{baseUrl}}/bpm/task/list-by-process-instance-id?processInstanceId=537cceb3-768c-11ec-afcd-a2380e71991a
tenant-id: 1
Authorization: Bearer {{token}}

View File

@ -0,0 +1,80 @@
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));
}
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel("流程活动的 Response VO")
@Data
public class BpmActivityRespVO {
@ApiModelProperty(value = "流程活动的标识", required = true, example = "1024")
private String key;
@ApiModelProperty(value = "流程活动的类型", required = true, example = "StartEvent")
private String type;
@ApiModelProperty(value = "流程活动的开始时间", required = true)
private Date startTime;
@ApiModelProperty(value = "流程活动的结束时间", required = true)
private Date endTime;
@ApiModelProperty(value = "关联的流程任务的编号", example = "2048", notes = "关联的流程任务,只有 UserTask 等类型才有")
private String taskId;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("流程实例的取消 Request VO")
@Data
public class BpmProcessInstanceCancelReqVO {
@ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
@NotEmpty(message = "流程实例的编号不能为空")
private String id;
@ApiModelProperty(value = "取消原因", required = true, example = "不请假了!")
@NotEmpty(message = "取消原因不能为空")
private String reason;
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.Map;
@ApiModel("流程实例的创建 Request VO")
@Data
public class BpmProcessInstanceCreateReqVO {
@ApiModelProperty(value = "流程定义的编号", required = true, example = "1024")
@NotEmpty(message = "流程定义编号不能为空")
private String processDefinitionId;
@ApiModelProperty(value = "变量实例")
private Map<String, Object> variables;
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
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("流程实例的分页 Item Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmProcessInstanceMyPageReqVO extends PageParam {
@ApiModelProperty(value = "流程名称", example = "芋道")
private String name;
@ApiModelProperty(value = "流程定义的编号", example = "2048")
private String processDefinitionId;
@ApiModelProperty(value = "流程实例的状态", notes = "参见 bpm_process_instance_status", example = "1")
private Integer status;
@ApiModelProperty(value = "流程实例的结果", notes = "参见 bpm_process_instance_result", example = "2")
private Integer result;
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
private String category;
@ApiModelProperty(value = "开始的创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginCreateTime;
@ApiModelProperty(value = "结束的创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endCreateTime;
}

View File

@ -0,0 +1,55 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@ApiModel("流程实例的分页 Item Response VO")
@Data
public class BpmProcessInstancePageItemRespVO {
@ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
private String name;
@ApiModelProperty(value = "流程定义的编号", required = true, example = "2048")
private String processDefinitionId;
@ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1")
private String category;
@ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1")
private Integer status;
@ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2")
private Integer result;
@ApiModelProperty(value = "提交时间", required = true)
private Date createTime;
@ApiModelProperty(value = "结束时间", required = true)
private Date endTime;
/**
* 当前任务
*/
private List<Task> tasks;
@ApiModel("流程任务")
@Data
public static class Task {
@ApiModelProperty(value = "流程任务的编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "任务名称", required = true, example = "芋道")
private String name;
}
}

View File

@ -0,0 +1,97 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ApiModel("流程实例的 Response VO")
@Data
public class BpmProcessInstanceRespVO {
@ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
private String name;
@ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1")
private String category;
@ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1")
private Integer status;
@ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2")
private Integer result;
@ApiModelProperty(value = "提交时间", required = true)
private Date createTime;
@ApiModelProperty(value = "结束时间", required = true)
private Date endTime;
@ApiModelProperty(value = "提交的表单值", required = true)
private Map<String, Object> formVariables;
@ApiModelProperty(value = "业务的唯一标识", example = "1", notes = "例如说,请假申请的编号")
private String businessKey;
/**
* 发起流程的用户
*/
private User startUser;
/**
* 流程定义
*/
private ProcessDefinition processDefinition;
@ApiModel("用户信息")
@Data
public static class User {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
private String nickname;
@ApiModelProperty(value = "部门编号", required = true, example = "1")
private Long deptId;
@ApiModelProperty(value = "部门名称", required = true, example = "研发部")
private String deptName;
}
@ApiModel("流程定义信息")
@Data
public static class ProcessDefinition {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
private Integer formType;
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private Long formId;
@ApiModelProperty(value = "表单的配置", required = true,
notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formConf;
@ApiModelProperty(value = "表单项的数组", required = true,
notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private List<String> formFields;
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomCreatePath;
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
private String formCustomViewPath;
@ApiModelProperty(value = "BPMN XML", required = true)
private String bpmnXml;
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("通过流程任务的 Request VO")
@Data
public class BpmTaskApproveReqVO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
@NotEmpty(message = "任务编号不能为空")
private String id;
@ApiModelProperty(value = "审批意见", required = true, example = "不错不错!")
@NotEmpty(message = "审批意见不能为空")
private String comment;
}

Some files were not shown because too many files have changed in this diff Show More