删除 yudao-bpm 项目,进一步精简项目
This commit is contained in:
parent
7412900e83
commit
205d2ae4a9
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.enums.definition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器的类型
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmProcessListenerType {
|
||||
|
||||
EXECUTION("execution", "执行监听器"),
|
||||
TASK("task", "任务执行器");
|
||||
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.enums.definition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器的值类型
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmProcessListenerValueType {
|
||||
|
||||
CLASS("class", "Java 类"),
|
||||
DELEGATE_EXPRESSION("delegateExpression", "代理表达式"),
|
||||
EXPRESSION("expression", "表达式");
|
||||
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.enums.task;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 流程实例/任务的删除原因枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmDeleteReasonEnum {
|
||||
|
||||
// ========== 流程实例的独有原因 ==========
|
||||
|
||||
REJECT_TASK("审批不通过任务,原因:{}"), // 场景:用户审批不通过任务。修改文案时,需要注意 isRejectReason 方法
|
||||
CANCEL_PROCESS_INSTANCE_BY_START_USER("用户主动取消流程,原因:{}"), // 场景:用户主动取消流程
|
||||
CANCEL_PROCESS_INSTANCE_BY_ADMIN("管理员【{}】取消流程,原因:{}"), // 场景:管理员取消流程
|
||||
|
||||
// ========== 流程任务的独有原因 ==========
|
||||
|
||||
CANCEL_BY_SYSTEM("系统自动取消"), // 场景:非常多,比如说:1)多任务审批已经满足条件,无需审批该任务;2)流程实例被取消,无需审批该任务;等等
|
||||
;
|
||||
|
||||
private final String reason;
|
||||
|
||||
/**
|
||||
* 格式化理由
|
||||
*
|
||||
* @param args 参数
|
||||
* @return 理由
|
||||
*/
|
||||
public String format(Object... args) {
|
||||
return StrUtil.format(reason, args);
|
||||
}
|
||||
|
||||
// ========== 逻辑 ==========
|
||||
|
||||
public static boolean isRejectReason(String reason) {
|
||||
return StrUtil.startWith(reason, "审批不通过任务,原因:");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.enums.task;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 流程任务的加签类型枚举
|
||||
*
|
||||
* @author kehaiyou
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskSignTypeEnum {
|
||||
|
||||
/**
|
||||
* 向前加签,需要前置任务审批完成,才回到原审批人
|
||||
*/
|
||||
BEFORE("before", "向前加签"),
|
||||
/**
|
||||
* 向后加签,需要后置任务全部审批完,才会通过原审批人节点
|
||||
*/
|
||||
AFTER("after", "向后加签");
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final String type;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static String nameOfType(String type) {
|
||||
for (BpmTaskSignTypeEnum value : values()) {
|
||||
if (value.type.equals(type)) {
|
||||
return value.name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BpmTaskSignTypeEnum of(String type) {
|
||||
return ArrayUtil.firstMatch(value -> value.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.enums.task;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 流程任务 Task 的状态枚举
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskStatusEnum {
|
||||
|
||||
RUNNING(1, "审批中"),
|
||||
APPROVE(2, "审批通过"),
|
||||
REJECT(3, "审批不通过"),
|
||||
CANCEL(4, "已取消"),
|
||||
|
||||
RETURN(5, "已退回"),
|
||||
DELEGATE(6, "委派中"),
|
||||
|
||||
/**
|
||||
* 使用场景:
|
||||
* 1. 任务被向后【加签】时,它在审批通过后,会变成 APPROVING 这个状态,然后等到【加签】出来的任务都被审批后,才会变成 APPROVE 审批通过
|
||||
*/
|
||||
APPROVING(7, "审批通过中"),
|
||||
/**
|
||||
* 使用场景:
|
||||
* 1. 任务被向前【加签】时,它会变成 WAIT 状态,需要等待【加签】出来的任务被审批后,它才能继续变为 RUNNING 继续审批
|
||||
* 2. 任务被向后【加签】时,【加签】出来的任务处于 WAIT 状态,它们需要等待该任务被审批后,它们才能继续变为 RUNNING 继续审批
|
||||
*/
|
||||
WAIT(0, "待审批");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
* <p>
|
||||
* 如果新增时,注意 {@link #isEndStatus(Integer)} 是否需要变更
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* 判断该状态是否已经处于 End 最终状态
|
||||
* <p>
|
||||
* 主要用于一些状态更新的逻辑,如果已经是最终状态,就不再进行更新
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isEndStatus(Integer status) {
|
||||
return ObjectUtils.equalsAny(status,
|
||||
APPROVE.getStatus(), REJECT.getStatus(), CANCEL.getStatus(),
|
||||
RETURN.getStatus(), APPROVING.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition;
|
||||
|
||||
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 cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - BPM 流程分类")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/category")
|
||||
@Validated
|
||||
public class BpmCategoryController {
|
||||
|
||||
@Resource
|
||||
private BpmCategoryService categoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建流程分类")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:category:create')")
|
||||
public CommonResult<Long> createCategory(@Valid @RequestBody BpmCategorySaveReqVO createReqVO) {
|
||||
return success(categoryService.createCategory(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新流程分类")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:category:update')")
|
||||
public CommonResult<Boolean> updateCategory(@Valid @RequestBody BpmCategorySaveReqVO updateReqVO) {
|
||||
categoryService.updateCategory(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除流程分类")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:category:delete')")
|
||||
public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
|
||||
categoryService.deleteCategory(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得流程分类")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:category:query')")
|
||||
public CommonResult<BpmCategoryRespVO> getCategory(@RequestParam("id") Long id) {
|
||||
BpmCategoryDO category = categoryService.getCategory(id);
|
||||
return success(BeanUtils.toBean(category, BpmCategoryRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得流程分类分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:category:query')")
|
||||
public CommonResult<PageResult<BpmCategoryRespVO>> getCategoryPage(@Valid BpmCategoryPageReqVO pageReqVO) {
|
||||
PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BpmCategoryRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取流程分类的精简信息列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
|
||||
public CommonResult<List<BpmCategoryRespVO>> getCategorySimpleList() {
|
||||
List<BpmCategoryDO> list = categoryService.getCategoryListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
list.sort(Comparator.comparingInt(BpmCategoryDO::getSort));
|
||||
return success(convertList(list, category -> new BpmCategoryRespVO().setId(category.getId())
|
||||
.setName(category.getName()).setCode(category.getCode())));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionSaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessExpressionDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessExpressionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - BPM 流程表达式")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-expression")
|
||||
@Validated
|
||||
public class BpmProcessExpressionController {
|
||||
|
||||
@Resource
|
||||
private BpmProcessExpressionService processExpressionService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建流程表达式")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-expression:create')")
|
||||
public CommonResult<Long> createProcessExpression(@Valid @RequestBody BpmProcessExpressionSaveReqVO createReqVO) {
|
||||
return success(processExpressionService.createProcessExpression(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新流程表达式")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-expression:update')")
|
||||
public CommonResult<Boolean> updateProcessExpression(@Valid @RequestBody BpmProcessExpressionSaveReqVO updateReqVO) {
|
||||
processExpressionService.updateProcessExpression(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除流程表达式")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-expression:delete')")
|
||||
public CommonResult<Boolean> deleteProcessExpression(@RequestParam("id") Long id) {
|
||||
processExpressionService.deleteProcessExpression(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得流程表达式")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-expression:query')")
|
||||
public CommonResult<BpmProcessExpressionRespVO> getProcessExpression(@RequestParam("id") Long id) {
|
||||
BpmProcessExpressionDO processExpression = processExpressionService.getProcessExpression(id);
|
||||
return success(BeanUtils.toBean(processExpression, BpmProcessExpressionRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得流程表达式分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-expression:query')")
|
||||
public CommonResult<PageResult<BpmProcessExpressionRespVO>> getProcessExpressionPage(
|
||||
@Valid BpmProcessExpressionPageReqVO pageReqVO) {
|
||||
PageResult<BpmProcessExpressionDO> pageResult = processExpressionService.getProcessExpressionPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BpmProcessExpressionRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessListenerDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessListenerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - BPM 流程监听器")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-listener")
|
||||
@Validated
|
||||
public class BpmProcessListenerController {
|
||||
|
||||
@Resource
|
||||
private BpmProcessListenerService processListenerService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建流程监听器")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-listener:create')")
|
||||
public CommonResult<Long> createProcessListener(@Valid @RequestBody BpmProcessListenerSaveReqVO createReqVO) {
|
||||
return success(processListenerService.createProcessListener(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新流程监听器")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-listener:update')")
|
||||
public CommonResult<Boolean> updateProcessListener(@Valid @RequestBody BpmProcessListenerSaveReqVO updateReqVO) {
|
||||
processListenerService.updateProcessListener(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除流程监听器")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-listener:delete')")
|
||||
public CommonResult<Boolean> deleteProcessListener(@RequestParam("id") Long id) {
|
||||
processListenerService.deleteProcessListener(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得流程监听器")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-listener:query')")
|
||||
public CommonResult<BpmProcessListenerRespVO> getProcessListener(@RequestParam("id") Long id) {
|
||||
BpmProcessListenerDO processListener = processListenerService.getProcessListener(id);
|
||||
return success(BeanUtils.toBean(processListener, BpmProcessListenerRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得流程监听器分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-listener:query')")
|
||||
public CommonResult<PageResult<BpmProcessListenerRespVO>> getProcessListenerPage(
|
||||
@Valid BpmProcessListenerPageReqVO pageReqVO) {
|
||||
PageResult<BpmProcessListenerDO> pageResult = processListenerService.getProcessListenerPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BpmProcessListenerRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程分类分页 Request VO")
|
||||
@Data
|
||||
public class BpmCategoryPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "分类名", example = "王五")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分类标志", example = "OA")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "分类状态", example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程分类 Response VO")
|
||||
@Data
|
||||
public class BpmCategoryRespVO {
|
||||
|
||||
@Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "分类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程分类新增/修改 Request VO")
|
||||
@Data
|
||||
public class BpmCategorySaveReqVO {
|
||||
|
||||
@Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
@NotEmpty(message = "分类名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分类描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
|
||||
@NotEmpty(message = "分类标志不能为空")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "分类状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "分类排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程表达式分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmProcessExpressionPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "表达式名字", example = "李四")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "表达式状态", example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程表达式 Response VO")
|
||||
@Data
|
||||
public class BpmProcessExpressionRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3870")
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表达式名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@ExcelProperty("表达式名字")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "表达式状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "表达式", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String expression;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程表达式新增/修改 Request VO")
|
||||
@Data
|
||||
public class BpmProcessExpressionSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3870")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表达式名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@NotEmpty(message = "表达式名字不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "表达式状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "表达式状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "表达式", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "表达式不能为空")
|
||||
private String expression;
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 动态表单创建/更新 Request VO")
|
||||
@Data
|
||||
public class BpmFormSaveReqVO {
|
||||
|
||||
@Schema(description = "表单编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
@NotNull(message = "表单名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "表单的配置-JSON 字符串", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "表单的配置不能为空")
|
||||
private String conf;
|
||||
|
||||
@Schema(description = "表单项的数组-JSON 字符串的数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "表单项的数组不能为空")
|
||||
private List<String> fields;
|
||||
|
||||
@Schema(description = "表单状态-参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "表单状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程监听器分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmProcessListenerPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "监听器名字", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "监听器类型", example = "execution")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "监听事件", example = "start")
|
||||
private String event;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程监听器 Response VO")
|
||||
@Data
|
||||
public class BpmProcessListenerRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13089")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "监听器名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "监听器类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "execution")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "监听器状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "监听事件", requiredMode = Schema.RequiredMode.REQUIRED, example = "start")
|
||||
private String event;
|
||||
|
||||
@Schema(description = "监听器值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "class")
|
||||
private String valueType;
|
||||
|
||||
@Schema(description = "监听器值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String value;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - BPM 流程监听器新增/修改 Request VO")
|
||||
@Data
|
||||
public class BpmProcessListenerSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13089")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "监听器名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotEmpty(message = "监听器名字不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "监听器类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "execution")
|
||||
@NotEmpty(message = "监听器类型不能为空")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "监听器状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "监听器状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "监听事件", requiredMode = Schema.RequiredMode.REQUIRED, example = "start")
|
||||
@NotEmpty(message = "监听事件不能为空")
|
||||
private String event;
|
||||
|
||||
@Schema(description = "监听器值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "class")
|
||||
@NotEmpty(message = "监听器值类型不能为空")
|
||||
private String valueType;
|
||||
|
||||
@Schema(description = "监听器值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "监听器值不能为空")
|
||||
private String value;
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceCopyRespVO {
|
||||
|
||||
@Schema(description = "抄送主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "发起人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
|
||||
private Long startUserId;
|
||||
@Schema(description = "发起人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
private String startUserName;
|
||||
|
||||
@Schema(description = "流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "A233")
|
||||
private String processInstanceId;
|
||||
@Schema(description = "流程实例的名称")
|
||||
private String processInstanceName;
|
||||
@Schema(description = "流程实例的发起时间")
|
||||
private LocalDateTime processInstanceStartTime;
|
||||
|
||||
@Schema(description = "发起抄送的任务编号")
|
||||
private String taskId;
|
||||
@Schema(description = "发起抄送的任务名称")
|
||||
private String taskName;
|
||||
|
||||
@Schema(description = "抄送人")
|
||||
private String creator;
|
||||
@Schema(description = "抄送人昵称")
|
||||
private String creatorName;
|
||||
|
||||
@Schema(description = "抄送时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 加签任务的创建(加签) Request VO")
|
||||
@Data
|
||||
public class BpmTaskSignCreateReqVO {
|
||||
|
||||
@Schema(description = "需要加签的任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "加签的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
|
||||
@NotEmpty(message = "加签用户不能为空")
|
||||
private Set<Long> userIds;
|
||||
|
||||
@Schema(description = "加签类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "before")
|
||||
@NotEmpty(message = "加签类型不能为空")
|
||||
private String type; // 参见 BpmTaskSignTypeEnum 枚举
|
||||
|
||||
@Schema(description = "加签原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "需要加签")
|
||||
@NotEmpty(message = "加签原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* BPM 流程分类 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("bpm_category")
|
||||
@KeySequence("bpm_category_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmCategoryDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 分类名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分类标志
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 分类描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类状态
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 分类排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* BPM 流程表达式 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("bpm_process_expression")
|
||||
@KeySequence("bpm_process_expression_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmProcessExpressionDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 表达式名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 表达式状态
|
||||
*
|
||||
* 枚举 {@link TODO common_status 对应的类}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 表达式
|
||||
*/
|
||||
private String expression;
|
||||
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器 DO
|
||||
*
|
||||
* 目的:本质上它是流程监听器的模版,用于 BPMN 在设计时,直接选择这些模版
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "bpm_process_listener")
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmProcessListenerDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键 ID,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 监听器名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 监听类型
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.module.bpm.enums.definition.BpmProcessListenerType}
|
||||
*
|
||||
* 1. execution:ExecutionListener <a href="https://tkjohn.github.io/flowable-userguide/#executionListeners">执行监听器</a>
|
||||
* 2. task:TaskListener <a href="https://tkjohn.github.io/flowable-userguide/#taskListeners">任务监听器</a>
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 监听事件
|
||||
*
|
||||
* execution 时:start、end
|
||||
* task 时:create 创建、assignment 指派、complete 完成、delete 删除、update 更新、timeout 超时
|
||||
*/
|
||||
private String event;
|
||||
|
||||
/**
|
||||
* 值类型
|
||||
*
|
||||
* 1. class:Java 类,ExecutionListener 需要 {@link org.flowable.engine.delegate.JavaDelegate},TaskListener 需要 {@link org.flowable.engine.delegate.TaskListener}
|
||||
* 2. delegateExpression:委托表达式,在 class 的基础上,需要注册到 Spring 容器里,后续表达式通过 Spring Bean 名称即可
|
||||
* 3. expression:表达式,一个普通类的普通方法,将这个普通类注册到 Spring 容器中,然后表达式中还可以执行这个类中的方法
|
||||
*/
|
||||
private String valueType;
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.mysql.category;
|
||||
|
||||
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.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 流程分类 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmCategoryMapper extends BaseMapperX<BpmCategoryDO> {
|
||||
|
||||
default PageResult<BpmCategoryDO> selectPage(BpmCategoryPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<BpmCategoryDO>()
|
||||
.likeIfPresent(BpmCategoryDO::getName, reqVO.getName())
|
||||
.likeIfPresent(BpmCategoryDO::getCode, reqVO.getCode())
|
||||
.eqIfPresent(BpmCategoryDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(BpmCategoryDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByAsc(BpmCategoryDO::getSort));
|
||||
}
|
||||
|
||||
default BpmCategoryDO selectByName(String name) {
|
||||
return selectOne(BpmCategoryDO::getName, name);
|
||||
}
|
||||
|
||||
default BpmCategoryDO selectByCode(String code) {
|
||||
return selectOne(BpmCategoryDO::getCode, code);
|
||||
}
|
||||
|
||||
default List<BpmCategoryDO> selectListByCode(Collection<String> codes) {
|
||||
return selectList(BpmCategoryDO::getCode, codes);
|
||||
}
|
||||
|
||||
default List<BpmCategoryDO> selectListByStatus(Integer status) {
|
||||
return selectList(BpmCategoryDO::getStatus, status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BpmProcessDefinitionInfoMapper extends BaseMapperX<BpmProcessDefinitionInfoDO> {
|
||||
|
||||
default List<BpmProcessDefinitionInfoDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
|
||||
return selectList(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionIds);
|
||||
}
|
||||
|
||||
default BpmProcessDefinitionInfoDO selectByProcessDefinitionId(String processDefinitionId) {
|
||||
return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessExpressionDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* BPM 流程表达式 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmProcessExpressionMapper extends BaseMapperX<BpmProcessExpressionDO> {
|
||||
|
||||
default PageResult<BpmProcessExpressionDO> selectPage(BpmProcessExpressionPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessExpressionDO>()
|
||||
.likeIfPresent(BpmProcessExpressionDO::getName, reqVO.getName())
|
||||
.eqIfPresent(BpmProcessExpressionDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(BpmProcessExpressionDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(BpmProcessExpressionDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
|
||||
|
||||
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.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessListenerDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmProcessListenerMapper extends BaseMapperX<BpmProcessListenerDO> {
|
||||
|
||||
default PageResult<BpmProcessListenerDO> selectPage(BpmProcessListenerPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessListenerDO>()
|
||||
.likeIfPresent(BpmProcessListenerDO::getName, reqVO.getName())
|
||||
.eqIfPresent(BpmProcessListenerDO::getType, reqVO.getType())
|
||||
.eqIfPresent(BpmProcessListenerDO::getEvent, reqVO.getEvent())
|
||||
.eqIfPresent(BpmProcessListenerDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(BpmProcessListenerDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
|
||||
import lombok.Setter;
|
||||
import org.flowable.bpmn.model.Activity;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
|
||||
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 自定义的【串行】的【多个】流程任务的 assignee 负责人的分配
|
||||
*
|
||||
* 本质上,实现和 {@link BpmParallelMultiInstanceBehavior} 一样,只是继承的类不一样
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Setter
|
||||
public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceBehavior {
|
||||
|
||||
private BpmTaskCandidateInvoker taskCandidateInvoker;
|
||||
|
||||
public BpmSequentialMultiInstanceBehavior(Activity activity, AbstractBpmnActivityBehavior innerActivityBehavior) {
|
||||
super(activity, innerActivityBehavior);
|
||||
}
|
||||
|
||||
/**
|
||||
* 逻辑和 {@link BpmParallelMultiInstanceBehavior#resolveNrOfInstances(DelegateExecution)} 类似
|
||||
*
|
||||
* 差异的点:是在【第二步】的时候,需要返回 LinkedHashSet 集合!因为它需要有序!
|
||||
*/
|
||||
@Override
|
||||
protected int resolveNrOfInstances(DelegateExecution execution) {
|
||||
// 第一步,设置 collectionVariable 和 CollectionVariable
|
||||
// 从 execution.getVariable() 读取所有任务处理人的 key
|
||||
super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
|
||||
super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
|
||||
// 从 execution.getVariable() 读取当前所有任务处理的人的 key
|
||||
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
|
||||
|
||||
// 第二步,获取任务的所有处理人
|
||||
Set<Long> assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!!
|
||||
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
||||
return assigneeUserIds.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
|
||||
|
||||
/**
|
||||
* {@link BpmTaskCandidateStrategy} 的调用者,用于调用对应的策略,实现任务的候选人的计算
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class BpmTaskCandidateInvoker {
|
||||
|
||||
private final Map<BpmTaskCandidateStrategyEnum, BpmTaskCandidateStrategy> strategyMap = new HashMap<>();
|
||||
|
||||
private final AdminUserApi adminUserApi;
|
||||
|
||||
public BpmTaskCandidateInvoker(List<BpmTaskCandidateStrategy> strategyList,
|
||||
AdminUserApi adminUserApi) {
|
||||
strategyList.forEach(strategy -> {
|
||||
BpmTaskCandidateStrategy oldStrategy = strategyMap.put(strategy.getStrategy(), strategy);
|
||||
Assert.isNull(oldStrategy, "策略(%s) 重复", strategy.getStrategy());
|
||||
});
|
||||
this.adminUserApi = adminUserApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验流程模型的任务分配规则全部都配置了
|
||||
* 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
|
||||
*
|
||||
* @param bpmnBytes BPMN XML
|
||||
*/
|
||||
public void validateBpmnConfig(byte[] bpmnBytes) {
|
||||
BpmnModel bpmnModel = BpmnModelUtils.getBpmnModel(bpmnBytes);
|
||||
assert bpmnModel != null;
|
||||
List<UserTask> userTaskList = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class);
|
||||
// 遍历所有的 UserTask,校验审批人配置
|
||||
userTaskList.forEach(userTask -> {
|
||||
// 1. 非空校验
|
||||
Integer strategy = BpmnModelUtils.parseCandidateStrategy(userTask);
|
||||
String param = BpmnModelUtils.parseCandidateParam(userTask);
|
||||
if (strategy == null) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG, userTask.getName());
|
||||
}
|
||||
BpmTaskCandidateStrategy candidateStrategy = getCandidateStrategy(strategy);
|
||||
if (candidateStrategy.isParamRequired() && StrUtil.isBlank(param)) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG, userTask.getName());
|
||||
}
|
||||
// 2. 具体策略校验
|
||||
getCandidateStrategy(strategy).validateParam(param);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算任务的候选人
|
||||
*
|
||||
* @param execution 执行任务
|
||||
* @return 用户编号集合
|
||||
*/
|
||||
@DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人
|
||||
public Set<Long> calculateUsers(DelegateExecution execution) {
|
||||
Integer strategy = BpmnModelUtils.parseCandidateStrategy(execution.getCurrentFlowElement());
|
||||
String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement());
|
||||
// 1.1 计算任务的候选人
|
||||
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsers(execution, param);
|
||||
// 1.2 移除被禁用的用户
|
||||
removeDisableUsers(userIds);
|
||||
|
||||
// 2. 校验是否有候选人
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
log.error("[calculateUsers][流程任务({}/{}/{}) 任务规则({}/{}) 找不到候选人]", execution.getId(),
|
||||
execution.getProcessDefinitionId(), execution.getCurrentActivityId(), strategy, param);
|
||||
throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
|
||||
}
|
||||
return userIds;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void removeDisableUsers(Set<Long> assigneeUserIds) {
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
return;
|
||||
}
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);
|
||||
assigneeUserIds.removeIf(id -> {
|
||||
AdminUserRespDTO user = userMap.get(id);
|
||||
return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
|
||||
});
|
||||
}
|
||||
|
||||
private BpmTaskCandidateStrategy getCandidateStrategy(Integer strategy) {
|
||||
BpmTaskCandidateStrategyEnum strategyEnum = BpmTaskCandidateStrategyEnum.valueOf(strategy);
|
||||
Assert.notNull(strategyEnum, "策略(%s) 不存在", strategy);
|
||||
BpmTaskCandidateStrategy strategyObj = strategyMap.get(strategyEnum);
|
||||
Assert.notNull(strategyObj, "策略(%s) 不存在", strategy);
|
||||
return strategyObj;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* BPM 任务的候选人的策略接口
|
||||
*
|
||||
* 例如说:分配审批人
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskCandidateStrategy {
|
||||
|
||||
/**
|
||||
* 对应策略
|
||||
*
|
||||
* @return 策略
|
||||
*/
|
||||
BpmTaskCandidateStrategyEnum getStrategy();
|
||||
|
||||
/**
|
||||
* 校验参数
|
||||
*
|
||||
* @param param 参数
|
||||
*/
|
||||
void validateParam(String param);
|
||||
|
||||
/**
|
||||
* 基于执行任务,获得任务的候选用户们
|
||||
*
|
||||
* @param execution 执行任务
|
||||
* @return 用户编号集合
|
||||
*/
|
||||
Set<Long> calculateUsers(DelegateExecution execution, String param);
|
||||
|
||||
/**
|
||||
* 是否一定要输入参数
|
||||
*
|
||||
* @return 是否
|
||||
*/
|
||||
default boolean isParamRequired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.expression;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 分配给发起人审批的 Expression 流程表达式
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskAssignStartUserExpression {
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
/**
|
||||
* 计算审批的候选人
|
||||
*
|
||||
* @param execution 流程执行实体
|
||||
* @return 发起人
|
||||
*/
|
||||
public Set<Long> calculateUsers(ExecutionEntityImpl execution) {
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
||||
return SetUtils.asSet(startUserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 部门的负责人 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateDeptLeaderStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.DEPT_LEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
Set<Long> deptIds = StrUtils.splitToLongSet(param);
|
||||
deptApi.validateDeptList(deptIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Set<Long> deptIds = StrUtils.splitToLongSet(param);
|
||||
List<DeptRespDTO> depts = deptApi.getDeptList(deptIds);
|
||||
return convertSet(depts, DeptRespDTO::getLeaderUserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 部门的成员 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateDeptMemberStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.DEPT_MEMBER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
Set<Long> deptIds = StrUtils.splitToLongSet(param);
|
||||
deptApi.validateDeptList(deptIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Set<Long> deptIds = StrUtils.splitToLongSet(param);
|
||||
List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(deptIds);
|
||||
return convertSet(users, AdminUserRespDTO::getId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import org.dromara.hutool.core.convert.Convert;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 流程表达式 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateExpressionStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.EXPRESSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
// do nothing 因为它基本做不了校验
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Object result = FlowableUtils.getExpressionValue(execution, param);
|
||||
return Convert.toSet(Long.class, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
|
||||
|
||||
/**
|
||||
* 用户组 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateGroupStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private BpmUserGroupService userGroupService;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.USER_GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
Set<Long> groupIds = StrUtils.splitToLongSet(param);
|
||||
userGroupService.getUserGroupList(groupIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Set<Long> groupIds = StrUtils.splitToLongSet(param);
|
||||
List<BpmUserGroupDO> groups = userGroupService.getUserGroupList(groupIds);
|
||||
return convertSetByFlatMap(groups, BpmUserGroupDO::getUserIds, Collection::stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 岗位 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidatePostStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private PostApi postApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
Set<Long> postIds = StrUtils.splitToLongSet(param);
|
||||
postApi.validPostList(postIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Set<Long> postIds = StrUtils.splitToLongSet(param);
|
||||
List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(postIds);
|
||||
return convertSet(users, AdminUserRespDTO::getId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateRoleStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private RoleApi roleApi;
|
||||
@Resource
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.ROLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
Set<Long> roleIds = StrUtils.splitToLongSet(param);
|
||||
roleApi.validRoleList(roleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Set<Long> roleIds = StrUtils.splitToLongSet(param);
|
||||
return permissionApi.getUserRoleIdListByRoleIds(roleIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 发起人自选 {@link BpmTaskCandidateUserStrategy} 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateStartUserSelectStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.START_USER_SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||
Assert.notNull(processInstance, "流程实例({})不能为空", execution.getProcessInstanceId());
|
||||
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processInstance);
|
||||
Assert.notNull(startUserSelectAssignees, "流程实例({}) 的发起人自选审批人不能为空",
|
||||
execution.getProcessInstanceId());
|
||||
// 获得审批人
|
||||
List<Long> assignees = startUserSelectAssignees.get(execution.getCurrentActivityId());
|
||||
return new LinkedHashSet<>(assignees);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParamRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得发起人自选审批人的 UserTask 列表
|
||||
*
|
||||
* @param bpmnModel BPMN 模型
|
||||
* @return UserTask 列表
|
||||
*/
|
||||
public static List<UserTask> getStartUserSelectUserTaskList(BpmnModel bpmnModel) {
|
||||
if (bpmnModel == null) {
|
||||
return null;
|
||||
}
|
||||
List<UserTask> userTaskList = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class);
|
||||
if (CollUtil.isEmpty(userTaskList)) {
|
||||
return null;
|
||||
}
|
||||
userTaskList.removeIf(userTask -> !Objects.equals(BpmnModelUtils.parseCandidateStrategy(userTask),
|
||||
BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy()));
|
||||
return userTaskList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateUserStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
adminUserApi.validateUserList(StrUtils.splitToLongSet(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
return StrUtils.splitToLongSet(param);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
|
||||
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
|
||||
/**
|
||||
* BPM 通用常量
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class BpmConstants {
|
||||
|
||||
/**
|
||||
* 流程实例的变量 - 状态
|
||||
*
|
||||
* @see ProcessInstance#getProcessVariables()
|
||||
*/
|
||||
public static final String PROCESS_INSTANCE_VARIABLE_STATUS = "PROCESS_STATUS";
|
||||
/**
|
||||
* 流程实例的变量 - 发起用户选择的审批人 Map
|
||||
*
|
||||
* @see ProcessInstance#getProcessVariables()
|
||||
*/
|
||||
public static final String PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES = "PROCESS_START_USER_SELECT_ASSIGNEES";
|
||||
|
||||
/**
|
||||
* 任务的变量 - 状态
|
||||
*
|
||||
* @see org.flowable.task.api.Task#getTaskLocalVariables()
|
||||
*/
|
||||
public static final String TASK_VARIABLE_STATUS = "TASK_STATUS";
|
||||
/**
|
||||
* 任务的变量 - 理由
|
||||
*
|
||||
* 例如说:审批通过、不通过的理由
|
||||
*
|
||||
* @see org.flowable.task.api.Task#getTaskLocalVariables()
|
||||
*/
|
||||
public static final String TASK_VARIABLE_REASON = "TASK_REASON";
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 任务的候选人策略枚举
|
||||
*
|
||||
* 例如说:分配给指定人审批
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskCandidateStrategyEnum {
|
||||
|
||||
ROLE(10, "角色"),
|
||||
DEPT_MEMBER(20, "部门的成员"), // 包括负责人
|
||||
DEPT_LEADER(21, "部门的负责人"),
|
||||
POST(22, "岗位"),
|
||||
USER(30, "用户"),
|
||||
START_USER_SELECT(35, "发起人自选"), // 申请人自己,可在提交申请时选择此节点的审批人
|
||||
USER_GROUP(40, "用户组"),
|
||||
EXPRESSION(60, "流程表达式"), // 表达式 ExpressionManager
|
||||
;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer strategy;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
public static BpmTaskCandidateStrategyEnum valueOf(Integer strategy) {
|
||||
return ArrayUtil.firstMatch(o -> o.getStrategy().equals(strategy), values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
|
||||
|
||||
/**
|
||||
* BPMN XML 常量信息
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmnModelConstants {
|
||||
|
||||
String BPMN_FILE_SUFFIX = ".bpmn";
|
||||
|
||||
/**
|
||||
* BPMN 中的命名空间
|
||||
*/
|
||||
String NAMESPACE = "http://flowable.org/bpmn";
|
||||
|
||||
/**
|
||||
* BPMN UserTask 的扩展属性,用于标记候选人策略
|
||||
*/
|
||||
String USER_TASK_CANDIDATE_STRATEGY = "candidateStrategy";
|
||||
/**
|
||||
* BPMN UserTask 的扩展属性,用于标记候选人参数
|
||||
*/
|
||||
String USER_TASK_CANDIDATE_PARAM = "candidateParam";
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.exection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.JavaDelegate;
|
||||
|
||||
/**
|
||||
* 类型为 class 的 ExecutionListener 监听器示例
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class DemoDelegateClassExecutionListener implements JavaDelegate {
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
log.info("[execute][execution({}) 被调用!变量有:{}]", execution.getId(),
|
||||
execution.getCurrentFlowableListener().getFieldExtensions());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.exection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.JavaDelegate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 类型为 delegateExpression 的 ExecutionListener 监听器示例
|
||||
*
|
||||
* 和 {@link DemoDelegateClassExecutionListener} 的差异是,需要注册到 Spring 中
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DemoDelegateExpressionExecutionListener implements JavaDelegate {
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
log.info("[execute][execution({}) 被调用!变量有:{}]", execution.getId(),
|
||||
execution.getCurrentFlowableListener().getFieldExtensions());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.exection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 类型为 expression 的 ExecutionListener 监听器示例
|
||||
*
|
||||
* 和 {@link DemoDelegateClassExecutionListener} 的差异是,需要注册到 Spring 中,但不用实现 {@link org.flowable.engine.delegate.JavaDelegate} 接口
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DemoSpringExpressionExecutionListener {
|
||||
|
||||
public void execute(DelegateExecution execution) {
|
||||
log.info("[execute][execution({}) 被调用!变量有:{}]", execution.getId(),
|
||||
execution.getCurrentFlowableListener().getFieldExtensions());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.task;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
|
||||
/**
|
||||
* 类型为 class 的 TaskListener 监听器示例
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class DemoDelegateClassTaskListener implements TaskListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
log.info("[execute][task({}) 被调用]", delegateTask.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.task;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 类型为 delegateExpression 的 TaskListener 监听器示例
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DemoDelegateExpressionTaskListener implements TaskListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
log.info("[execute][task({}) 被调用]", delegateTask.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.task;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 类型为 expression 的 TaskListener 监听器示例
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DemoSpringExpressionTaskListener {
|
||||
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
log.info("[execute][task({}) 被调用]", delegateTask.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
|
||||
import org.flowable.common.engine.api.delegate.Expression;
|
||||
import org.flowable.common.engine.api.variable.VariableContainer;
|
||||
import org.flowable.common.engine.impl.el.ExpressionManager;
|
||||
import org.flowable.common.engine.impl.identity.Authentication;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.TaskInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Flowable 相关的工具方法
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class FlowableUtils {
|
||||
|
||||
// ========== User 相关的工具方法 ==========
|
||||
|
||||
public static void setAuthenticatedUserId(Long userId) {
|
||||
Authentication.setAuthenticatedUserId(String.valueOf(userId));
|
||||
}
|
||||
|
||||
public static void clearAuthenticatedUserId() {
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
}
|
||||
|
||||
// ========== Execution 相关的工具方法 ==========
|
||||
|
||||
/**
|
||||
* 格式化多实例(并签、或签)的 collectionVariable 变量(多实例对应的多审批人列表)
|
||||
*
|
||||
* @param activityId 活动编号
|
||||
* @return collectionVariable 变量
|
||||
*/
|
||||
public static String formatExecutionCollectionVariable(String activityId) {
|
||||
return activityId + "_assignees";
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化多实例(并签、或签)的 collectionElementVariable 变量(当前实例对应的一个审批人)
|
||||
*
|
||||
* @param activityId 活动编号
|
||||
* @return collectionElementVariable 变量
|
||||
*/
|
||||
public static String formatExecutionCollectionElementVariable(String activityId) {
|
||||
return activityId + "_assignee";
|
||||
}
|
||||
|
||||
// ========== ProcessInstance 相关的工具方法 ==========
|
||||
|
||||
public static Integer getProcessInstanceStatus(ProcessInstance processInstance) {
|
||||
return getProcessInstanceStatus(processInstance.getProcessVariables());
|
||||
}
|
||||
|
||||
public static Integer getProcessInstanceStatus(HistoricProcessInstance processInstance) {
|
||||
return getProcessInstanceStatus(processInstance.getProcessVariables());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的状态
|
||||
*
|
||||
* @param processVariables 流程实例的 variables
|
||||
* @return 状态
|
||||
*/
|
||||
private static Integer getProcessInstanceStatus(Map<String, Object> processVariables) {
|
||||
return (Integer) processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的表单
|
||||
*
|
||||
* @param processInstance 流程实例
|
||||
* @return 表单
|
||||
*/
|
||||
public static Map<String, Object> getProcessInstanceFormVariable(HistoricProcessInstance processInstance) {
|
||||
Map<String, Object> formVariables = new HashMap<>(processInstance.getProcessVariables());
|
||||
filterProcessInstanceFormVariable(formVariables);
|
||||
return formVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤流程实例的表单
|
||||
*
|
||||
* 为什么要过滤?目前使用 processVariables 存储所有流程实例的拓展字段,需要过滤掉一部分的系统字段,从而实现表单的展示
|
||||
*
|
||||
* @param processVariables 流程实例的 variables
|
||||
* @return 过滤后的表单
|
||||
*/
|
||||
public static Map<String, Object> filterProcessInstanceFormVariable(Map<String, Object> processVariables) {
|
||||
processVariables.remove(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
||||
return processVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的发起用户选择的审批人 Map
|
||||
*
|
||||
* @param processInstance 流程实例
|
||||
* @return 发起用户选择的审批人 Map
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, List<Long>> getStartUserSelectAssignees(ProcessInstance processInstance) {
|
||||
return (Map<String, List<Long>>) processInstance.getProcessVariables().get(
|
||||
BpmConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES);
|
||||
}
|
||||
|
||||
// ========== Task 相关的工具方法 ==========
|
||||
|
||||
/**
|
||||
* 获得任务的状态
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 状态
|
||||
*/
|
||||
public static Integer getTaskStatus(TaskInfo task) {
|
||||
return (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得任务的审批原因
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 审批原因
|
||||
*/
|
||||
public static String getTaskReason(TaskInfo task) {
|
||||
return (String) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_REASON);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得任务的表单
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 表单
|
||||
*/
|
||||
public static Map<String, Object> getTaskFormVariable(TaskInfo task) {
|
||||
Map<String, Object> formVariables = new HashMap<>(task.getTaskLocalVariables());
|
||||
filterTaskFormVariable(formVariables);
|
||||
return formVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤任务的表单
|
||||
*
|
||||
* 为什么要过滤?目前使用 taskLocalVariables 存储所有任务的拓展字段,需要过滤掉一部分的系统字段,从而实现表单的展示
|
||||
*
|
||||
* @param taskLocalVariables 任务的 taskLocalVariables
|
||||
* @return 过滤后的表单
|
||||
*/
|
||||
public static Map<String, Object> filterTaskFormVariable(Map<String, Object> taskLocalVariables) {
|
||||
taskLocalVariables.remove(BpmConstants.TASK_VARIABLE_STATUS);
|
||||
taskLocalVariables.remove(BpmConstants.TASK_VARIABLE_REASON);
|
||||
return taskLocalVariables;
|
||||
}
|
||||
|
||||
// ========== Expression 相关的工具方法 ==========
|
||||
|
||||
public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
||||
assert processEngineConfiguration != null;
|
||||
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
|
||||
assert expressionManager != null;
|
||||
Expression expression = expressionManager.createExpression(expressionString);
|
||||
return expression.getValue(variableContainer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* BPM 流程分类 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmCategoryService {
|
||||
|
||||
/**
|
||||
* 创建流程分类
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createCategory(@Valid BpmCategorySaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新流程分类
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateCategory(@Valid BpmCategorySaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除流程分类
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程分类
|
||||
*
|
||||
* @param id 编号
|
||||
* @return BPM 流程分类
|
||||
*/
|
||||
BpmCategoryDO getCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程分类分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 流程分类分页
|
||||
*/
|
||||
PageResult<BpmCategoryDO> getCategoryPage(BpmCategoryPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得流程分类 Map,基于指定编码
|
||||
*
|
||||
* @param codes 编号数组
|
||||
* @return 流程分类 Map
|
||||
*/
|
||||
default Map<String, BpmCategoryDO> getCategoryMap(Collection<String> codes) {
|
||||
return convertMap(getCategoryListByCode(codes), BpmCategoryDO::getCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程分类列表,基于指定编码
|
||||
*
|
||||
* @return 流程分类列表
|
||||
*/
|
||||
List<BpmCategoryDO> getCategoryListByCode(Collection<String> codes);
|
||||
|
||||
/**
|
||||
* 获得流程分类列表,基于指定状态
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 流程分类列表
|
||||
*/
|
||||
List<BpmCategoryDO> getCategoryListByStatus(Integer status);
|
||||
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* BPM 流程分类 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmCategoryServiceImpl implements BpmCategoryService {
|
||||
|
||||
@Resource
|
||||
private BpmCategoryMapper bpmCategoryMapper;
|
||||
|
||||
@Override
|
||||
public Long createCategory(BpmCategorySaveReqVO createReqVO) {
|
||||
// 校验唯一
|
||||
validateCategoryNameUnique(createReqVO);
|
||||
validateCategoryCodeUnique(createReqVO);
|
||||
// 插入
|
||||
BpmCategoryDO category = BeanUtils.toBean(createReqVO, BpmCategoryDO.class);
|
||||
bpmCategoryMapper.insert(category);
|
||||
return category.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCategory(BpmCategorySaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateCategoryExists(updateReqVO.getId());
|
||||
validateCategoryNameUnique(updateReqVO);
|
||||
validateCategoryCodeUnique(updateReqVO);
|
||||
// 更新
|
||||
BpmCategoryDO updateObj = BeanUtils.toBean(updateReqVO, BpmCategoryDO.class);
|
||||
bpmCategoryMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
private void validateCategoryNameUnique(BpmCategorySaveReqVO updateReqVO) {
|
||||
BpmCategoryDO category = bpmCategoryMapper.selectByName(updateReqVO.getName());
|
||||
if (category == null
|
||||
|| ObjUtil.equal(category.getId(), updateReqVO.getId())) {
|
||||
return;
|
||||
}
|
||||
throw exception(CATEGORY_NAME_DUPLICATE, updateReqVO.getName());
|
||||
}
|
||||
|
||||
private void validateCategoryCodeUnique(BpmCategorySaveReqVO updateReqVO) {
|
||||
BpmCategoryDO category = bpmCategoryMapper.selectByCode(updateReqVO.getCode());
|
||||
if (category == null
|
||||
|| ObjUtil.equal(category.getId(), updateReqVO.getId())) {
|
||||
return;
|
||||
}
|
||||
throw exception(CATEGORY_CODE_DUPLICATE, updateReqVO.getCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCategory(Long id) {
|
||||
// 校验存在
|
||||
validateCategoryExists(id);
|
||||
// 删除
|
||||
bpmCategoryMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateCategoryExists(Long id) {
|
||||
if (bpmCategoryMapper.selectById(id) == null) {
|
||||
throw exception(CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmCategoryDO getCategory(Long id) {
|
||||
return bpmCategoryMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmCategoryDO> getCategoryPage(BpmCategoryPageReqVO pageReqVO) {
|
||||
return bpmCategoryMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmCategoryDO> getCategoryListByCode(Collection<String> codes) {
|
||||
if (CollUtil.isEmpty(codes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return bpmCategoryMapper.selectListByCode(codes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmCategoryDO> getCategoryListByStatus(Integer status) {
|
||||
return bpmCategoryMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionSaveReqVO;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessExpressionDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
/**
|
||||
* BPM 流程表达式 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmProcessExpressionService {
|
||||
|
||||
/**
|
||||
* 创建流程表达式
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createProcessExpression(@Valid BpmProcessExpressionSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新流程表达式
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateProcessExpression(@Valid BpmProcessExpressionSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除流程表达式
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteProcessExpression(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程表达式
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程表达式
|
||||
*/
|
||||
BpmProcessExpressionDO getProcessExpression(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程表达式分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 流程表达式分页
|
||||
*/
|
||||
PageResult<BpmProcessExpressionDO> getProcessExpressionPage(BpmProcessExpressionPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.expression.BpmProcessExpressionSaveReqVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessExpressionDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessExpressionMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* BPM 流程表达式 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmProcessExpressionServiceImpl implements BpmProcessExpressionService {
|
||||
|
||||
@Resource
|
||||
private BpmProcessExpressionMapper processExpressionMapper;
|
||||
|
||||
@Override
|
||||
public Long createProcessExpression(BpmProcessExpressionSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
BpmProcessExpressionDO processExpression = BeanUtils.toBean(createReqVO, BpmProcessExpressionDO.class);
|
||||
processExpressionMapper.insert(processExpression);
|
||||
// 返回
|
||||
return processExpression.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessExpression(BpmProcessExpressionSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateProcessExpressionExists(updateReqVO.getId());
|
||||
// 更新
|
||||
BpmProcessExpressionDO updateObj = BeanUtils.toBean(updateReqVO, BpmProcessExpressionDO.class);
|
||||
processExpressionMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProcessExpression(Long id) {
|
||||
// 校验存在
|
||||
validateProcessExpressionExists(id);
|
||||
// 删除
|
||||
processExpressionMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateProcessExpressionExists(Long id) {
|
||||
if (processExpressionMapper.selectById(id) == null) {
|
||||
throw exception(PROCESS_EXPRESSION_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmProcessExpressionDO getProcessExpression(Long id) {
|
||||
return processExpressionMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessExpressionDO> getProcessExpressionPage(BpmProcessExpressionPageReqVO pageReqVO) {
|
||||
return processExpressionMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerSaveReqVO;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessListenerDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmProcessListenerService {
|
||||
|
||||
/**
|
||||
* 创建流程监听器
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createProcessListener(@Valid BpmProcessListenerSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新流程监听器
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateProcessListener(@Valid BpmProcessListenerSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除流程监听器
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteProcessListener(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程监听器
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 流程监听器
|
||||
*/
|
||||
BpmProcessListenerDO getProcessListener(Long id);
|
||||
|
||||
/**
|
||||
* 获得流程监听器分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 流程监听器分页
|
||||
*/
|
||||
PageResult<BpmProcessListenerDO> getProcessListenerPage(BpmProcessListenerPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.listener.BpmProcessListenerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessListenerDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessListenerMapper;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmProcessListenerType;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmProcessListenerValueType;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.JavaDelegate;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* BPM 流程监听器 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmProcessListenerServiceImpl implements BpmProcessListenerService {
|
||||
|
||||
@Resource
|
||||
private BpmProcessListenerMapper processListenerMapper;
|
||||
|
||||
@Override
|
||||
public Long createProcessListener(BpmProcessListenerSaveReqVO createReqVO) {
|
||||
// 校验
|
||||
validateCreateProcessListenerValue(createReqVO);
|
||||
// 插入
|
||||
BpmProcessListenerDO processListener = BeanUtils.toBean(createReqVO, BpmProcessListenerDO.class);
|
||||
processListenerMapper.insert(processListener);
|
||||
return processListener.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProcessListener(BpmProcessListenerSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateProcessListenerExists(updateReqVO.getId());
|
||||
validateCreateProcessListenerValue(updateReqVO);
|
||||
// 更新
|
||||
BpmProcessListenerDO updateObj = BeanUtils.toBean(updateReqVO, BpmProcessListenerDO.class);
|
||||
processListenerMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
private void validateCreateProcessListenerValue(BpmProcessListenerSaveReqVO createReqVO) {
|
||||
// class 类型
|
||||
if (createReqVO.getValueType().equals(BpmProcessListenerValueType.CLASS.getType())) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(createReqVO.getValue());
|
||||
if (createReqVO.getType().equals(BpmProcessListenerType.EXECUTION.getType())
|
||||
&& !JavaDelegate.class.isAssignableFrom(clazz)) {
|
||||
throw exception(PROCESS_LISTENER_CLASS_IMPLEMENTS_ERROR, createReqVO.getValue(),
|
||||
JavaDelegate.class.getName());
|
||||
} else if (createReqVO.getType().equals(BpmProcessListenerType.TASK.getType())
|
||||
&& !TaskListener.class.isAssignableFrom(clazz)) {
|
||||
throw exception(PROCESS_LISTENER_CLASS_IMPLEMENTS_ERROR, createReqVO.getValue(),
|
||||
TaskListener.class.getName());
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw exception(PROCESS_LISTENER_CLASS_NOT_FOUND, createReqVO.getValue());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 表达式
|
||||
if (!StrUtil.startWith(createReqVO.getValue(), "${") || !StrUtil.endWith(createReqVO.getValue(), "}")) {
|
||||
throw exception(PROCESS_LISTENER_EXPRESSION_INVALID, createReqVO.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProcessListener(Long id) {
|
||||
// 校验存在
|
||||
validateProcessListenerExists(id);
|
||||
// 删除
|
||||
processListenerMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateProcessListenerExists(Long id) {
|
||||
if (processListenerMapper.selectById(id) == null) {
|
||||
throw exception(PROCESS_LISTENER_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmProcessListenerDO getProcessListener(Long id) {
|
||||
return processListenerMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessListenerDO> getProcessListenerPage(BpmProcessListenerPageReqVO pageReqVO) {
|
||||
return processListenerMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.task;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 流程抄送 Service 接口
|
||||
*
|
||||
* 现在是在审批的时候进行流程抄送
|
||||
*/
|
||||
public interface BpmProcessInstanceCopyService {
|
||||
|
||||
/**
|
||||
* 流程实例的抄送
|
||||
*
|
||||
* @param userIds 抄送的用户编号
|
||||
* @param taskId 流程任务编号
|
||||
*/
|
||||
void createProcessInstanceCopy(Collection<Long> userIds, String taskId);
|
||||
|
||||
/**
|
||||
* 获得抄送的流程的分页
|
||||
*
|
||||
* @param userId 当前登录用户
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 抄送的分页结果
|
||||
*/
|
||||
PageResult<BpmProcessInstanceCopyDO> getProcessInstanceCopyPage(Long userId,
|
||||
BpmProcessInstanceCopyPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.task;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceCopyMapper;
|
||||
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 流程抄送 Service 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService {
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyMapper processInstanceCopyMapper;
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
|
||||
@Override
|
||||
public void createProcessInstanceCopy(Collection<Long> userIds, String taskId) {
|
||||
// 1.1 校验任务存在
|
||||
Task task = taskService.getTask(taskId);
|
||||
if (ObjectUtil.isNull(task)) {
|
||||
throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
|
||||
}
|
||||
// 1.2 校验流程实例存在
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
|
||||
if (processInstance == null) {
|
||||
throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
// 1.3 校验流程定义存在
|
||||
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
|
||||
processInstance.getProcessDefinitionId());
|
||||
if (processDefinition == null) {
|
||||
throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 2. 创建抄送流程
|
||||
List<BpmProcessInstanceCopyDO> copyList = convertList(userIds, userId -> new BpmProcessInstanceCopyDO()
|
||||
.setUserId(userId).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
|
||||
.setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName())
|
||||
.setCategory(processDefinition.getCategory()).setTaskId(taskId).setTaskName(task.getName()));
|
||||
processInstanceCopyMapper.insertBatch(copyList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessInstanceCopyDO> getProcessInstanceCopyPage(Long userId,
|
||||
BpmProcessInstanceCopyPageReqVO pageReqVO) {
|
||||
return processInstanceCopyMapper.selectPage(userId, pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateUserStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link BpmTaskCandidateInvoker} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class BpmTaskCandidateInvokerTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateInvoker taskCandidateInvoker;
|
||||
|
||||
@Mock
|
||||
private AdminUserApi adminUserApi;
|
||||
@Spy
|
||||
private BpmTaskCandidateStrategy strategy = new BpmTaskCandidateUserStrategy();
|
||||
@Spy
|
||||
private List<BpmTaskCandidateStrategy> strategyList = Collections.singletonList(strategy);
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
DelegateExecution execution = mock(DelegateExecution.class);
|
||||
// mock 方法(DelegateExecution)
|
||||
UserTask userTask = mock(UserTask.class);
|
||||
when(execution.getCurrentFlowElement()).thenReturn(userTask);
|
||||
when(userTask.getAttributeValue(eq(BpmnModelConstants.NAMESPACE), eq(BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY)))
|
||||
.thenReturn(BpmTaskCandidateStrategyEnum.USER.getStrategy().toString());
|
||||
when(userTask.getAttributeValue(eq(BpmnModelConstants.NAMESPACE), eq(BpmnModelConstants.USER_TASK_CANDIDATE_PARAM)))
|
||||
.thenReturn(param);
|
||||
// mock 方法(adminUserApi)
|
||||
AdminUserRespDTO user1 = randomPojo(AdminUserRespDTO.class, o -> o.setId(1L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
AdminUserRespDTO user2 = randomPojo(AdminUserRespDTO.class, o -> o.setId(2L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
Map<Long, AdminUserRespDTO> userMap = MapUtil.builder(user1.getId(), user1)
|
||||
.put(user2.getId(), user2).build();
|
||||
when(adminUserApi.getUserMap(eq(asSet(1L, 2L)))).thenReturn(userMap);
|
||||
|
||||
// 调用
|
||||
Set<Long> results = taskCandidateInvoker.calculateUsers(execution);
|
||||
// 断言
|
||||
assertEquals(asSet(1L, 2L), results);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveDisableUsers() {
|
||||
// 准备参数. 1L 可以找到;2L 是禁用的;3L 找不到
|
||||
Set<Long> assigneeUserIds = asSet(1L, 2L, 3L);
|
||||
// mock 方法
|
||||
AdminUserRespDTO user1 = randomPojo(AdminUserRespDTO.class, o -> o.setId(1L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
AdminUserRespDTO user2 = randomPojo(AdminUserRespDTO.class, o -> o.setId(2L)
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
Map<Long, AdminUserRespDTO> userMap = MapUtil.builder(user1.getId(), user1)
|
||||
.put(user2.getId(), user2).build();
|
||||
when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap);
|
||||
|
||||
// 调用
|
||||
taskCandidateInvoker.removeDisableUsers(assigneeUserIds);
|
||||
// 断言
|
||||
assertEquals(asSet(1L), assigneeUserIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BpmTaskCandidateDeptLeaderStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateDeptLeaderStrategy strategy;
|
||||
|
||||
@Mock
|
||||
private DeptApi deptApi;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
// mock 方法
|
||||
DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L));
|
||||
DeptRespDTO dept2 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(22L));
|
||||
when(deptApi.getDeptList(eq(asSet(1L, 2L)))).thenReturn(asList(dept1, dept2));
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(11L, 22L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BpmTaskCandidateDeptMemberStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateDeptMemberStrategy strategy;
|
||||
|
||||
@Mock
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "11,22";
|
||||
// mock 方法
|
||||
List<AdminUserRespDTO> users = convertList(asSet(11L, 22L),
|
||||
id -> new AdminUserRespDTO().setId(id));
|
||||
when(adminUserApi.getUserListByDeptIds(eq(asSet(11L, 22L)))).thenReturn(users);
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(11L, 22L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class BpmTaskCandidateExpressionStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateExpressionStrategy strategy;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
DelegateExecution execution = mock(DelegateExecution.class);
|
||||
// mock 方法
|
||||
flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(execution), eq(param)))
|
||||
.thenReturn(asSet(1L, 2L));
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(execution, param);
|
||||
// 断言
|
||||
assertEquals(asSet(1L, 2L), results);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BpmTaskCandidateGroupStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateGroupStrategy strategy;
|
||||
|
||||
@Mock
|
||||
private BpmUserGroupService userGroupService;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
// mock 方法
|
||||
BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(11L, 12L)));
|
||||
BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(21L, 22L)));
|
||||
when(userGroupService.getUserGroupList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(userGroup1, userGroup2));
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(11L, 12L, 21L, 22L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BpmTaskCandidatePostStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidatePostStrategy strategy;
|
||||
|
||||
@Mock
|
||||
private PostApi postApi;
|
||||
@Mock
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
// mock 方法
|
||||
List<AdminUserRespDTO> users = convertList(asSet(11L, 22L),
|
||||
id -> new AdminUserRespDTO().setId(id));
|
||||
when(adminUserApi.getUserListByPostIds(eq(asSet(1L, 2L)))).thenReturn(users);
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(11L, 22L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BpmTaskCandidateRoleStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateRoleStrategy strategy;
|
||||
|
||||
@Mock
|
||||
private RoleApi roleApi;
|
||||
@Mock
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
// mock 方法
|
||||
when(permissionApi.getUserRoleIdListByRoleIds(eq(asSet(1L, 2L))))
|
||||
.thenReturn(asSet(11L, 22L));
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(11L, 22L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class BpmTaskCandidateUserStrategyTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private BpmTaskCandidateUserStrategy strategy;
|
||||
|
||||
@Test
|
||||
public void testCalculateUsers() {
|
||||
// 准备参数
|
||||
String param = "1,2";
|
||||
|
||||
// 调用
|
||||
Set<Long> results = strategy.calculateUsers(null, param);
|
||||
// 断言
|
||||
assertEquals(asSet(1L, 2L), results);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
package cn.iocoder.yudao.module.bpm.service.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link BpmCategoryServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(BpmCategoryServiceImpl.class)
|
||||
public class BpmCategoryServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private BpmCategoryServiceImpl categoryService;
|
||||
|
||||
@Resource
|
||||
private BpmCategoryMapper categoryMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateCategory_success() {
|
||||
// 准备参数
|
||||
BpmCategorySaveReqVO createReqVO = randomPojo(BpmCategorySaveReqVO.class).setId(null)
|
||||
.setStatus(randomCommonStatus());
|
||||
|
||||
// 调用
|
||||
Long categoryId = categoryService.createCategory(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(categoryId);
|
||||
// 校验记录的属性是否正确
|
||||
BpmCategoryDO category = categoryMapper.selectById(categoryId);
|
||||
assertPojoEquals(createReqVO, category, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_success() {
|
||||
// mock 数据
|
||||
BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
|
||||
categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class, o -> {
|
||||
o.setId(dbCategory.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
categoryService.updateCategory(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
BpmCategoryDO category = categoryMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, category);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_notExists() {
|
||||
// 准备参数
|
||||
BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> categoryService.updateCategory(updateReqVO), CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_success() {
|
||||
// mock 数据
|
||||
BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
|
||||
categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbCategory.getId();
|
||||
|
||||
// 调用
|
||||
categoryService.deleteCategory(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(categoryMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCategoryPage() {
|
||||
// mock 数据
|
||||
BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class, o -> { // 等会查询到
|
||||
o.setName("芋头");
|
||||
o.setCode("xiaodun");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2023, 2, 2));
|
||||
});
|
||||
categoryMapper.insert(dbCategory);
|
||||
// 测试 name 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("小盾")));
|
||||
// 测试 code 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCode("tudou")));
|
||||
// 测试 status 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(buildTime(2024, 2, 2))));
|
||||
// 准备参数
|
||||
BpmCategoryPageReqVO reqVO = new BpmCategoryPageReqVO();
|
||||
reqVO.setName("芋");
|
||||
reqVO.setCode("xiao");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbCategory, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue