BPM:优化 convert 的逻辑

This commit is contained in:
YunaiV 2024-03-20 21:32:01 +08:00
parent c104191821
commit e5444c5d47
43 changed files with 287 additions and 459 deletions

View File

@ -5,14 +5,13 @@ import lombok.Data;
import org.springframework.context.ApplicationEvent;
/**
* 流程实例的结果发生变化的 Event
* 定位由于额外增加了 {@link BpmProcessInstanceExtDO#getResult()} 结果所以增加该事件
* 流程实例的状态结果发生变化的 Event
*
* @author 芋道源码
*/
@SuppressWarnings("ALL")
@Data
public class BpmProcessInstanceResultEvent extends ApplicationEvent {
public class BpmProcessInstanceStatusEvent extends ApplicationEvent {
/**
* 流程实例的编号
@ -27,15 +26,15 @@ public class BpmProcessInstanceResultEvent extends ApplicationEvent {
/**
* 流程实例的结果
*/
@NotNull(message = "流程实例的结果不能为空")
private Integer result;
@NotNull(message = "流程实例的状态不能为空")
private Integer status;
/**
* 流程实例对应的业务标识
* 例如说请假
*/
private String businessKey;
public BpmProcessInstanceResultEvent(Object source) {
public BpmProcessInstanceStatusEvent(Object source) {
super(source);
}

View File

@ -4,15 +4,15 @@ import cn.hutool.core.util.StrUtil;
import org.springframework.context.ApplicationListener;
/**
* {@link BpmProcessInstanceResultEvent} 的监听器
* {@link BpmProcessInstanceStatusEvent} 的监听器
*
* @author 芋道源码
*/
public abstract class BpmProcessInstanceResultEventListener
implements ApplicationListener<BpmProcessInstanceResultEvent> {
public abstract class BpmProcessInstanceStatusEventListener
implements ApplicationListener<BpmProcessInstanceStatusEvent> {
@Override
public final void onApplicationEvent(BpmProcessInstanceResultEvent event) {
public final void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
if (!StrUtil.equals(event.getProcessDefinitionKey(), getProcessDefinitionKey())) {
return;
}
@ -29,6 +29,6 @@ public abstract class BpmProcessInstanceResultEventListener
*
* @param event 事件
*/
protected abstract void onEvent(BpmProcessInstanceResultEvent event);
protected abstract void onEvent(BpmProcessInstanceStatusEvent event);
}

View File

@ -1,23 +1,26 @@
package cn.iocoder.yudao.module.bpm.controller.admin.definition;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.*;
import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
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 jakarta.annotation.Resource;
import jakarta.validation.Valid;
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 = "管理后台 - 动态表单")
@RestController
@ -31,14 +34,14 @@ public class BpmFormController {
@PostMapping("/create")
@Operation(summary = "创建动态表单")
@PreAuthorize("@ss.hasPermission('bpm:form:create')")
public CommonResult<Long> createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) {
public CommonResult<Long> createForm(@Valid @RequestBody BpmFormSaveReqVO createReqVO) {
return success(formService.createForm(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新动态表单")
@PreAuthorize("@ss.hasPermission('bpm:form:update')")
public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) {
public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormSaveReqVO updateReqVO) {
formService.updateForm(updateReqVO);
return success(true);
}
@ -58,14 +61,15 @@ public class BpmFormController {
@PreAuthorize("@ss.hasPermission('bpm:form:query')")
public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) {
BpmFormDO form = formService.getForm(id);
return success(BpmFormConvert.INSTANCE.convert(form));
return success(BeanUtils.toBean(form, BpmFormRespVO.class));
}
@GetMapping("/list-all-simple")
@GetMapping({"/list-all-simple", "/simple-list"})
@Operation(summary = "获得动态表单的精简列表", description = "用于表单下拉框")
public CommonResult<List<BpmFormSimpleRespVO>> getSimpleForms() {
public CommonResult<List<BpmFormRespVO>> getFormSimpleList() {
List<BpmFormDO> list = formService.getFormList();
return success(BpmFormConvert.INSTANCE.convertList2(list));
return success(convertList(list, formDO -> // 只返回 idname 字段
new BpmFormRespVO().setId(formDO.getId()).setName(formDO.getName())));
}
@GetMapping("/page")
@ -73,7 +77,7 @@ public class BpmFormController {
@PreAuthorize("@ss.hasPermission('bpm:form:query')")
public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) {
PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO);
return success(BpmFormConvert.INSTANCE.convertPage(pageResult));
return success(BeanUtils.toBean(pageResult, BpmFormRespVO.class));
}
}

View File

@ -1,24 +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.*;
/**
* 动态表单 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class BpmFormBaseVO {
@Schema(description = "表单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotNull(message = "表单名称不能为空")
private String name;
@Schema(description = "表单状态-参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "表单状态不能为空")
private Integer status;
@Schema(description = "备注", example = "我是备注")
private String remark;
}

View File

@ -1,22 +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
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormCreateReqVO extends BpmFormBaseVO {
@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;
}

View File

@ -1,22 +1,23 @@
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 动态表单 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormRespVO extends BpmFormBaseVO {
public class BpmFormRespVO {
@Schema(description = "表单编号", requiredMode = Schema.RequiredMode.REQUIRED, 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;
@ -25,6 +26,13 @@ public class BpmFormRespVO extends BpmFormBaseVO {
@NotNull(message = "表单项的数组不能为空")
private List<String> fields;
@Schema(description = "表单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "表单状态不能为空")
private Integer status; // 参见 CommonStatusEnum 枚举
@Schema(description = "备注", example = "我是备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;

View File

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

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 流程表单精简 Response VO")
@Data
public class BpmFormSimpleRespVO {
@Schema(description = "表单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "表单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
}

View File

@ -1,25 +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.*;
import java.util.List;
@Schema(description = "管理后台 - 动态表单更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormUpdateReqVO extends BpmFormBaseVO {
@Schema(description = "表单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "表单编号不能为空")
private Long id;
@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;
}

View File

@ -50,7 +50,10 @@ public class BpmProcessDefinitionRespVO {
@Schema(description = "中断状态-参见 SuspensionState 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer suspensionState;
@Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime deploymentTime; // 需要从对应的 Deployment 读取
@Schema(description = "部署时间")
private LocalDateTime deploymentTime; // 需要从对应的 Deployment 读取非必须返回
@Schema(description = "BPMN XML")
private String bpmnXml; // 需要从对应的 BpmnModel 读取非必须返回
}

View File

@ -1,23 +1,22 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
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.oa.vo.BpmOALeaveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
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 jakarta.annotation.Resource;
import jakarta.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@ -49,7 +48,7 @@ public class BpmOALeaveController {
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<BpmOALeaveRespVO> getLeave(@RequestParam("id") Long id) {
BpmOALeaveDO leave = leaveService.getLeave(id);
return success(BpmOALeaveConvert.INSTANCE.convert(leave));
return success(BeanUtils.toBean(leave, BpmOALeaveRespVO.class));
}
@GetMapping("/page")
@ -57,7 +56,7 @@ public class BpmOALeaveController {
@Operation(summary = "获得请假申请分页")
public CommonResult<PageResult<BpmOALeaveRespVO>> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) {
PageResult<BpmOALeaveDO> pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO);
return success(BpmOALeaveConvert.INSTANCE.convertPage(pageResult));
return success(BeanUtils.toBean(pageResult, BpmOALeaveRespVO.class));
}
}

View File

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

View File

@ -1,16 +1,34 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
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 = "管理后台 - 请假申请创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOALeaveCreateReqVO extends BpmOALeaveBaseVO {
public class BpmOALeaveCreateReqVO {
@Schema(description = "请假的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "请假的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
@Schema(description = "请假类型-参见 bpm_oa_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer type;
@Schema(description = "原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "阅读芋道源码")
private String reason;
@AssertTrue(message = "结束时间,需要在开始时间之后")
public boolean isEndTimeValid() {

View File

@ -1,10 +1,14 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
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 = "管理后台 - 请假申请分页 Request VO")
@ -13,13 +17,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class BpmOALeavePageReqVO extends PageParam {
@Schema(description = "状态-参见 bpm_process_instance_result 枚举", example = "1")
private Integer result;
@Schema(description = "状态", example = "1")
private Integer status; // 参见 BpmProcessInstanceResultEnum 枚举
@Schema(description = "请假类型-参见 bpm_oa_type", example = "1")
@Schema(description = "请假类型参见 bpm_oa_type", example = "1")
private Integer type;
@Schema(description = "原因-模糊匹配", example = "阅读芋道源码")
@Schema(description = "原因模糊匹配", example = "阅读芋道源码")
private String reason;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@ -1,32 +1,36 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 请假申请 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOALeaveRespVO extends BpmOALeaveBaseVO {
public class BpmOALeaveRespVO {
@Schema(description = "请假表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "状态-参见 bpm_process_instance_result 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer result;
@Schema(description = "请假类型,参见 bpm_oa_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer type;
@Schema(description = "原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "阅读芋道源码")
private String reason;
@Schema(description = "申请时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "申请时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime createTime;
@Schema(description = "流程id")
@Schema(description = "请假的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "请假的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
@Schema(description = "流程编号")
private String processInstanceId;
@Schema(description = "审批结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
}

View File

@ -3,13 +3,19 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -45,10 +51,15 @@ public class BpmProcessInstanceController {
@Resource
private BpmCategoryService categoryService;
@Resource
private AdminUserApi adminUserApi;
@Resource
private DeptApi deptApi;
@GetMapping("/my-page")
@Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
public CommonResult<PageResult<BpmProcessInstanceRespVO>> getMyProcessInstancePage(
@Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
PageResult<HistoricProcessInstance> pageResult = processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
@ -62,7 +73,8 @@ public class BpmProcessInstanceController {
convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId));
Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
convertSet(processDefinitionMap.values(), ProcessDefinition::getCategory));
return success(BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, processDefinitionMap, categoryMap, taskMap));
return success(BpmProcessInstanceConvert.INSTANCE.buildMyProcessInstancePage(pageResult,
processDefinitionMap, categoryMap, taskMap));
}
@PostMapping("/create")
@ -77,7 +89,24 @@ public class BpmProcessInstanceController {
@Parameter(name = "id", description = "流程实例的编号", required = true)
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
return success(processInstanceService.getProcessInstanceVO(id));
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(id);
if (processInstance == null) {
return success(null);
}
// 拼接返回
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
processInstance.getProcessDefinitionId());
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
processInstance.getProcessDefinitionId());
String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());
AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
DeptRespDTO dept = null;
if (startUser != null) {
dept = deptApi.getDept(startUser.getDeptId());
}
return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstance(processInstance,
processDefinition, processDefinitionInfo, bpmnXml, startUser, dept));
}
@DeleteMapping("/cancel")

View File

@ -19,7 +19,7 @@ public class BpmActivityRespVO {
@Schema(description = "流程活动的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
@Schema(description = "关联的流程任务的编号-关联的流程任务,只有 UserTask 等类型才有", example = "2048")
private String taskId;
@Schema(description = "关联的流程任务的编号", example = "2048")
private String taskId; // 关联的流程任务只有 UserTask 等类型才有
}

View File

@ -1,54 +0,0 @@
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
// TODO @芋艿是不是要融合
@Schema(description = "管理后台 - 流程实例的分页 Item Response VO")
@Data
public class BpmProcessInstancePageItemRespVO {
@Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String id;
@Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private String processDefinitionId;
@Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String category;
@Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
private String categoryName;
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
@Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
/**
* 当前任务
*/
private List<Task> tasks;
@Schema(description = "流程任务")
@Data
public static class Task {
@Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String id;
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -19,12 +20,14 @@ public class BpmProcessInstanceRespVO {
@Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String category;
@Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
private String categoryName;
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
@Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
private LocalDateTime startTime;
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
@ -40,10 +43,17 @@ public class BpmProcessInstanceRespVO {
*/
private User startUser;
@Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private String processDefinitionId;
/**
* 流程定义
*/
private ProcessDefinition processDefinition;
private BpmProcessDefinitionRespVO processDefinition;
/**
* 当前审批中的任务
*/
private List<Task> tasks; // 仅在流程实例分页才返回
@Schema(description = "用户信息")
@Data
@ -61,30 +71,15 @@ public class BpmProcessInstanceRespVO {
}
@Schema(description = "流程定义信息")
@Schema(description = "流程任务")
@Data
public static class ProcessDefinition {
public static class Task {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String id;
@Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
private Integer formType;
@Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
private Long formId;
@Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
private String formConf;
@Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> formFields;
@Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
example = "/bpm/oa/leave/create")
private String formCustomCreatePath;
@Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
example = "/bpm/oa/leave/view")
private String formCustomViewPath;
@Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
private String bpmnXml;
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
}

View File

@ -42,9 +42,6 @@ public class BpmTaskRespVO {
*/
private BpmProcessInstanceRespVO.User assigneeUser;
// TODO @芋艿这个 key 有点问题应该是 taskDefinitionId
@Schema(description = "任务定义的标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "user-001")
private String definitionKey;
@Schema(description = "任务定义的标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "Activity_one")
private String taskDefinitionKey;

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.bpm.convert.definition;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSimpleRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 动态表单 Convert
*
* @author 芋艿
*/
@Mapper
public interface BpmFormConvert {
BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class);
BpmFormDO convert(BpmFormCreateReqVO bean);
BpmFormDO convert(BpmFormUpdateReqVO bean);
BpmFormRespVO convert(BpmFormDO bean);
List<BpmFormSimpleRespVO> convertList2(List<BpmFormDO> list);
PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page);
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.bpm.convert.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 请假申请 Convert
*
* @author 芋艿
*/
@Mapper
public interface BpmOALeaveConvert {
BpmOALeaveConvert INSTANCE = Mappers.getMapper(BpmOALeaveConvert.class);
BpmOALeaveDO convert(BpmOALeaveCreateReqVO bean);
BpmOALeaveRespVO convert(BpmOALeaveDO bean);
List<BpmOALeaveRespVO> convertList(List<BpmOALeaveDO> list);
PageResult<BpmOALeaveRespVO> convertPage(PageResult<BpmOALeaveDO> page);
}

View File

@ -4,12 +4,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@ -18,6 +18,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;
@ -30,39 +31,43 @@ import java.util.Map;
*
* @author 芋道源码
*/
@Mapper
public interface BpmProcessInstanceConvert {
BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<HistoricProcessInstance> pageResult,
Map<String, ProcessDefinition> processDefinitionMap,
Map<String, BpmCategoryDO> categoryMap,
Map<String, List<Task>> taskMap) {
PageResult<BpmProcessInstancePageItemRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstancePageItemRespVO.class);
default PageResult<BpmProcessInstanceRespVO> buildMyProcessInstancePage(PageResult<HistoricProcessInstance> pageResult,
Map<String, ProcessDefinition> processDefinitionMap,
Map<String, BpmCategoryDO> categoryMap,
Map<String, List<Task>> taskMap) {
PageResult<BpmProcessInstanceRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstanceRespVO.class);
for (int i = 0; i < pageResult.getList().size(); i++) {
BpmProcessInstancePageItemRespVO respVO = vpPageResult.getList().get(i);
BpmProcessInstanceRespVO respVO = vpPageResult.getList().get(i);
respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i)));
MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(),
processDefinition -> respVO.setCategory(processDefinition.getCategory()));
MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName()));
respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstancePageItemRespVO.Task.class));
respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstanceRespVO.Task.class));
}
return vpPageResult;
}
default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance,
ProcessDefinition processDefinition, BpmProcessDefinitionInfoDO processDefinitionExt,
String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
BpmProcessInstanceRespVO respVO = convert2(processInstance);
default BpmProcessInstanceRespVO buildProcessInstance(HistoricProcessInstance processInstance,
ProcessDefinition processDefinition,
BpmProcessDefinitionInfoDO processDefinitionExt,
String bpmnXml,
AdminUserRespDTO startUser,
DeptRespDTO dept) {
BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class);
respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance));
respVO.setFormVariables(FlowableUtils.filterProcessInstanceFormVariable(processInstance.getProcessVariables()));
// definition
respVO.setProcessDefinition(convert2(processDefinition));
respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class));
copyTo(processDefinitionExt, respVO.getProcessDefinition());
respVO.getProcessDefinition().setBpmnXml(bpmnXml);
// user
if (startUser != null) {
respVO.setStartUser(convert2(startUser));
respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
if (dept != null) {
respVO.getStartUser().setDeptName(dept.getName());
}
@ -70,42 +75,27 @@ public interface BpmProcessInstanceConvert {
return respVO;
}
BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);
BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
@Mapping(source = "from.id", target = "to.id", ignore = true)
void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
event.setId(instance.getId());
event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
event.setBusinessKey(instance.getBusinessKey());
event.setResult(result);
return event;
default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, HistoricProcessInstance instance, Integer status) {
return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status)
.setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
}
// TODO @芋艿需要改下 key
default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {
BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
event.setId(instance.getId());
event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
event.setBusinessKey(instance.getBusinessKey());
event.setResult(result);
return event;
default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) {;
return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status)
.setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
}
default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){
return new BpmMessageSendWhenProcessInstanceApproveReqDTO()
default BpmMessageSendWhenProcessInstanceApproveReqDTO buildProcessInstanceApproveMessage(ProcessInstance instance) {
return new BpmMessageSendWhenProcessInstanceApproveReqDTO()
.setStartUserId(NumberUtils.parseLong(instance.getStartUserId()))
.setProcessInstanceId(instance.getId())
.setProcessInstanceName(instance.getName());
}
default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String reason) {
default BpmMessageSendWhenProcessInstanceRejectReqDTO buildProcessInstanceRejectMessage(ProcessInstance instance, String reason) {
return new BpmMessageSendWhenProcessInstanceRejectReqDTO()
.setProcessInstanceName(instance.getName())
.setProcessInstanceId(instance.getId())

View File

@ -6,10 +6,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@ -18,6 +18,7 @@ import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.Date;
@ -32,6 +33,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd
*
* @author 芋道源码
*/
@Mapper
public interface BpmTaskConvert {
BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);

View File

@ -57,12 +57,12 @@ public class BpmOALeaveDO extends BaseDO {
*/
private Long day;
/**
* 请假的结果
* 审批结果
*
* 枚举 {@link BpmTaskStatustEnum}
* 考虑到简单所以直接复用了 BpmProcessInstanceResultEnum 枚举也可以自己定义一个枚举哈
* 考虑到简单所以直接复用了 BpmProcessInstanceStatusEnum 枚举也可以自己定义一个枚举哈
*/
private Integer result;
private Integer status;
/**
* 对应的流程编号

View File

@ -19,7 +19,7 @@ public interface BpmOALeaveMapper extends BaseMapperX<BpmOALeaveDO> {
default PageResult<BpmOALeaveDO> selectPage(Long userId, BpmOALeavePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<BpmOALeaveDO>()
.eqIfPresent(BpmOALeaveDO::getUserId, userId)
.eqIfPresent(BpmOALeaveDO::getResult, reqVO.getResult())
.eqIfPresent(BpmOALeaveDO::getStatus, reqVO.getStatus())
.eqIfPresent(BpmOALeaveDO::getType, reqVO.getType())
.likeIfPresent(BpmOALeaveDO::getReason, reqVO.getReason())
.betweenIfPresent(BpmOALeaveDO::getCreateTime, reqVO.getCreateTime())

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.event;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.validation.annotation.Validated;
@ -8,7 +8,7 @@ import org.springframework.validation.annotation.Validated;
import jakarta.validation.Valid;
/**
* {@link BpmProcessInstanceResultEvent} 的生产者
* {@link BpmProcessInstanceStatusEvent} 的生产者
*
* @author 芋道源码
*/
@ -18,7 +18,7 @@ public class BpmProcessInstanceResultEventPublisher {
private final ApplicationEventPublisher publisher;
public void sendProcessInstanceResultEvent(@Valid BpmProcessInstanceResultEvent event) {
public void sendProcessInstanceResultEvent(@Valid BpmProcessInstanceStatusEvent event) {
publisher.publishEvent(event);
}

View File

@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.bpm.service.definition;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import jakarta.validation.Valid;
@ -26,14 +25,14 @@ public interface BpmFormService {
* @param createReqVO 创建信息
* @return 编号
*/
Long createForm(@Valid BpmFormCreateReqVO createReqVO);
Long createForm(@Valid BpmFormSaveReqVO createReqVO);
/**
* 更新动态表单
*
* @param updateReqVO 更新信息
*/
void updateForm(@Valid BpmFormUpdateReqVO updateReqVO);
void updateForm(@Valid BpmFormSaveReqVO updateReqVO);
/**
* 删除动态表单

View File

@ -4,10 +4,9 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
@ -33,22 +32,22 @@ public class BpmFormServiceImpl implements BpmFormService {
private BpmFormMapper formMapper;
@Override
public Long createForm(BpmFormCreateReqVO createReqVO) {
this.checkFields(createReqVO.getFields());
public Long createForm(BpmFormSaveReqVO createReqVO) {
this.vadateFields(createReqVO.getFields());
// 插入
BpmFormDO form = BpmFormConvert.INSTANCE.convert(createReqVO);
BpmFormDO form = BeanUtils.toBean(createReqVO, BpmFormDO.class);
formMapper.insert(form);
// 返回
return form.getId();
}
@Override
public void updateForm(BpmFormUpdateReqVO updateReqVO) {
this.checkFields(updateReqVO.getFields());
public void updateForm(BpmFormSaveReqVO updateReqVO) {
vadateFields(updateReqVO.getFields());
// 校验存在
this.validateFormExists(updateReqVO.getId());
validateFormExists(updateReqVO.getId());
// 更新
BpmFormDO updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO);
BpmFormDO updateObj = BeanUtils.toBean(updateReqVO, BpmFormDO.class);
formMapper.updateById(updateObj);
}
@ -94,7 +93,7 @@ public class BpmFormServiceImpl implements BpmFormService {
*
* @param fields field 数组
*/
private void checkFields(List<String> fields) {
private void vadateFields(List<String> fields) {
if (true) { // TODO 芋艿兼容 Vue3 工作流因为采用了新的表单设计器所以暂时不校验
return;
}

View File

@ -87,7 +87,7 @@ public class BpmModelServiceImpl implements BpmModelService {
@Override
@Transactional(rollbackFor = Exception.class)
public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) {
if (!ValidationUtils.isXmlNCName(createReqVO.getName())) {
if (!ValidationUtils.isXmlNCName(createReqVO.getKey())) {
throw exception(MODEL_KEY_VALID);
}
// 校验流程标识已经存在

View File

@ -29,9 +29,9 @@ public interface BpmOALeaveService {
* 更新请假申请的状态
*
* @param id 编号
* @param result 结果
* @param status 结果
*/
void updateLeaveResult(Long id, Integer result);
void updateLeaveStatus(Long id, Integer status);
/**
* 获得请假申请

View File

@ -2,19 +2,19 @@ package cn.iocoder.yudao.module.bpm.service.oa;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatustEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@ -47,8 +47,8 @@ public class BpmOALeaveServiceImpl implements BpmOALeaveService {
public Long createLeave(Long userId, BpmOALeaveCreateReqVO createReqVO) {
// 插入 OA 请假单
long day = LocalDateTimeUtil.between(createReqVO.getStartTime(), createReqVO.getEndTime()).toDays();
BpmOALeaveDO leave = BpmOALeaveConvert.INSTANCE.convert(createReqVO).setUserId(userId).setDay(day)
.setResult(BpmTaskStatustEnum.RUNNING.getStatus());
BpmOALeaveDO leave = BeanUtils.toBean(createReqVO, BpmOALeaveDO.class)
.setUserId(userId).setDay(day).setStatus(BpmTaskStatustEnum.RUNNING.getStatus());
leaveMapper.insert(leave);
// 发起 BPM 流程
@ -64,9 +64,9 @@ public class BpmOALeaveServiceImpl implements BpmOALeaveService {
}
@Override
public void updateLeaveResult(Long id, Integer result) {
public void updateLeaveStatus(Long id, Integer status) {
validateLeaveExists(id);
leaveMapper.updateById(new BpmOALeaveDO().setId(id).setResult(result));
leaveMapper.updateById(new BpmOALeaveDO().setId(id).setStatus(status));
}
private void validateLeaveExists(Long id) {

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.bpm.service.oa.listener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEventListener;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveServiceImpl;
import org.springframework.stereotype.Component;
@ -14,7 +14,7 @@ import jakarta.annotation.Resource;
* @author 芋道源码
*/
@Component
public class BpmOALeaveResultListener extends BpmProcessInstanceResultEventListener {
public class BpmOALeaveStatusListener extends BpmProcessInstanceStatusEventListener {
@Resource
private BpmOALeaveService leaveService;
@ -25,8 +25,8 @@ public class BpmOALeaveResultListener extends BpmProcessInstanceResultEventListe
}
@Override
protected void onEvent(BpmProcessInstanceResultEvent event) {
leaveService.updateLeaveResult(Long.parseLong(event.getBusinessKey()), event.getResult());
protected void onEvent(BpmProcessInstanceStatusEvent event) {
leaveService.updateLeaveStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
}
}

View File

@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import jakarta.validation.Valid;
import org.flowable.engine.delegate.event.FlowableCancelledEvent;
import org.flowable.engine.history.HistoricProcessInstance;
@ -115,14 +114,6 @@ public interface BpmProcessInstanceService {
*/
String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO);
/**
* 获得流程实例 VO 信息
*
* @param id 流程实例的编号
* @return 流程实例
*/
BpmProcessInstanceRespVO getProcessInstanceVO(String id);
/**
* 取消流程实例
*

View File

@ -187,8 +187,12 @@ public class BpmTaskServiceImpl implements BpmTaskService {
BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
// 3.3 调用 BPM complete 去完成任务
// 其中variables 是存储动态表单到 local 任务级别过滤一下避免 ProcessInstance 系统级的变量被占用
Map<String, Object> variables = FlowableUtils.filterTaskFormVariable(reqVO.getVariables());
taskService.complete(task.getId(), variables, true);
if (CollUtil.isNotEmpty(reqVO.getVariables())) {
Map<String, Object> variables = FlowableUtils.filterTaskFormVariable(reqVO.getVariables());
taskService.complete(task.getId(), variables, true);
} else {
taskService.complete(task.getId());
}
// 加签专属处理加签任务
handleParentTaskIfSign(task.getParentTaskId());

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
@ -43,7 +43,7 @@ public class BpmFormServiceTest extends BaseDbUnitTest {
@Test
public void testCreateForm_success() {
// 准备参数
BpmFormCreateReqVO reqVO = randomPojo(BpmFormCreateReqVO.class, o -> {
BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {
o.setConf("{}");
o.setFields(randomFields());
});

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupSaveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
import org.junit.jupiter.api.Assertions;
@ -56,7 +55,7 @@ public class BpmUserGroupServiceTest extends BaseDbUnitTest {
BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class);
userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据
// 准备参数
BpmUserGroupUpdateReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupUpdateReqVO.class, o -> {
BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class, o -> {
o.setId(dbUserGroup.getId()); // 设置更新的 ID
});
@ -70,7 +69,7 @@ public class BpmUserGroupServiceTest extends BaseDbUnitTest {
@Test
public void testUpdateUserGroup_notExists() {
// 准备参数
BpmUserGroupUpdateReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupUpdateReqVO.class);
BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class);
// 调用, 并断言异常
AssertUtils.assertServiceException(() -> userGroupService.updateUserGroup(reqVO), USER_GROUP_NOT_EXISTS);

View File

@ -3,7 +3,7 @@ CREATE TABLE IF NOT EXISTS "bpm_user_group" (
"name" varchar(63) NOT NULL,
"description" varchar(255) NOT NULL,
"status" tinyint NOT NULL,
"member_user_ids" varchar(255) NOT NULL,
"user_ids" varchar(255) NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.crm.service.contract.listener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEventListener;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl;
import jakarta.annotation.Resource;
@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
public class CrmContractResultListener extends BpmProcessInstanceResultEventListener {
public class CrmContractStatusListener extends BpmProcessInstanceStatusEventListener {
@Resource
private CrmContractService contractService;
@ -24,8 +24,8 @@ public class CrmContractResultListener extends BpmProcessInstanceResultEventList
}
@Override
protected void onEvent(BpmProcessInstanceResultEvent event) {
contractService.updateContractAuditStatus(Long.parseLong(event.getBusinessKey()), event.getResult());
protected void onEvent(BpmProcessInstanceStatusEvent event) {
contractService.updateContractAuditStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
}
}

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.crm.service.receivable.listener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEventListener;
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableServiceImpl;
import jakarta.annotation.Resource;
@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
public class CrmReceivableResultListener extends BpmProcessInstanceResultEventListener {
public class CrmReceivableStatusListener extends BpmProcessInstanceStatusEventListener {
@Resource
private CrmReceivableService receivableService;
@ -24,8 +24,8 @@ public class CrmReceivableResultListener extends BpmProcessInstanceResultEventLi
}
@Override
public void onEvent(BpmProcessInstanceResultEvent event) {
receivableService.updateReceivableAuditStatus(Long.parseLong(event.getBusinessKey()), event.getResult());
public void onEvent(BpmProcessInstanceStatusEvent event) {
receivableService.updateReceivableAuditStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
}
}

View File

@ -59,7 +59,7 @@ flowable:
database-schema-update: true # 设置为 false可通过 https://github.com/flowable/flowable-sql 初始化
db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置
check-process-definitions: false # 设置为 false禁用 /resources/processes 自动部署 BPMN XML 流程
history-level: full # full保存历史数据的最高级别可保存全部流程相关细节包括流程流转各节点参数
history-level: audit # full保存历史数据的最高级别可保存全部流程相关细节包括流程流转各节点参数
# MyBatis Plus 的配置项
mybatis-plus: