mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 11:40:05 +08:00
commit
70fe3d31bd
3017
sql/activiti.sql
Normal file
3017
sql/activiti.sql
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,9 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmFormConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import io.swagger.annotations.Api;
|
@ -1,8 +1,8 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.model.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.model.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.io.IoUtils;
|
||||
@ -47,7 +47,7 @@ public class BpmModelController {
|
||||
@ApiOperation(value = "新建模型")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:create')")
|
||||
public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) {
|
||||
return success(bpmModelService.createModel(createRetVO));
|
||||
return success(bpmModelService.createModel(createRetVO, null));
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@ -56,8 +56,8 @@ public class BpmModelController {
|
||||
public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
|
||||
BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
|
||||
// 读取文件
|
||||
createReqVO.setBpmnXml(IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false));
|
||||
return success(bpmModelService.createModel(createReqVO));
|
||||
String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);
|
||||
return success(bpmModelService.createModel(createReqVO, bpmnXml));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
@ -1,9 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
@ -0,0 +1,4 @@
|
||||
### 请求 /bpm/task-assign-rule/list 接口 => 成功
|
||||
GET {{baseUrl}}/bpm/task-assign-rule/list?processDefinitionId=leave:9:59689ba0-7284-11ec-965c-a2380e71991a
|
||||
tenant-id: 1
|
||||
Authorization: Bearer {{token}}
|
@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "任务分配规则")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/task-assign-rule")
|
||||
@Validated
|
||||
public class BpmTaskAssignRuleController {
|
||||
|
||||
@Resource
|
||||
private BpmTaskAssignRuleService taskAssignRuleService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
|
||||
@RequestParam(value = "modelId", required = false) String modelId,
|
||||
@RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
|
||||
return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
|
||||
return success(taskAssignRuleService.createTaskAssignRule(reqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
|
||||
taskAssignRuleService.updateTaskAssignRule(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmUserGroupConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserSimpleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.convert.user.SysUserConvert;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "用户组")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/user-group")
|
||||
@Validated
|
||||
public class BpmUserGroupController {
|
||||
|
||||
@Resource
|
||||
private BpmUserGroupService userGroupService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建用户组")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:user-group:create')")
|
||||
public CommonResult<Long> createUserGroup(@Valid @RequestBody BpmUserGroupCreateReqVO createReqVO) {
|
||||
return success(userGroupService.createUserGroup(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新用户组")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:user-group:update')")
|
||||
public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody BpmUserGroupUpdateReqVO updateReqVO) {
|
||||
userGroupService.updateUserGroup(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除用户组")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:user-group:delete')")
|
||||
public CommonResult<Boolean> deleteUserGroup(@RequestParam("id") Long id) {
|
||||
userGroupService.deleteUserGroup(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得用户组")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
|
||||
public CommonResult<BpmUserGroupRespVO> getUserGroup(@RequestParam("id") Long id) {
|
||||
BpmUserGroupDO userGroup = userGroupService.getUserGroup(id);
|
||||
return success(BpmUserGroupConvert.INSTANCE.convert(userGroup));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得用户组分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
|
||||
public CommonResult<PageResult<BpmUserGroupRespVO>> getUserGroupPage(@Valid BpmUserGroupPageReqVO pageVO) {
|
||||
PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(pageVO);
|
||||
return success(BpmUserGroupConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/list-all-simple")
|
||||
@ApiOperation(value = "获取用户组精简信息列表", notes = "只包含被开启的用户组,主要用于前端的下拉选项")
|
||||
public CommonResult<List<BpmUserGroupRespVO>> getSimpleUserGroups() {
|
||||
// 获用户门列表,只要开启状态的
|
||||
List<BpmUserGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// 排序后,返回给前端
|
||||
return success(BpmUserGroupConvert.INSTANCE.convertList2(list));
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 用户组 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class BpmUserGroupBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "组名", required = true, example = "芋道")
|
||||
@NotNull(message = "组名不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "描述", required = true, example = "芋道源码")
|
||||
@NotNull(message = "描述不能为空")
|
||||
private String description;
|
||||
|
||||
@ApiModelProperty(value = "成员编号数组", required = true, example = "1,2,3")
|
||||
@NotNull(message = "成员编号数组不能为空")
|
||||
private Set<Long> memberUserIds;
|
||||
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("用户组创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupCreateReqVO extends BpmUserGroupBaseVO {
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("用户组分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "组名", example = "芋道")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
@ApiModel("用户组 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupRespVO extends BpmUserGroupBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("用户组更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1024")
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@ -9,11 +9,11 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("流程模型的导入 Request VO")
|
||||
@ApiModel(value = "流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmModeImportReqVO extends BpmModelBaseVO {
|
||||
public class BpmModeImportReqVO extends BpmModelCreateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "BPMN 文件", required = true)
|
||||
@NotNull(message = "BPMN 文件不能为空")
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@ -27,7 +27,15 @@ public class BpmModelBaseVO {
|
||||
@NotEmpty(message = "流程分类不能为空")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty(value = "表单编号", example = "1024")
|
||||
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
|
||||
private Integer formType;
|
||||
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private Long formId;
|
||||
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
|
||||
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private String formCustomCreatePath;
|
||||
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
|
||||
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private String formCustomViewPath;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ApiModel("流程模型的创建 Request VO")
|
||||
@Data
|
||||
public class BpmModelCreateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "流程标识", required = true, example = "process_yudao")
|
||||
@NotEmpty(message = "流程标识不能为空")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty(value = "流程名称", required = true, example = "芋道")
|
||||
@NotEmpty(message = "流程名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "流程描述", example = "我是描述")
|
||||
private String description;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ApiModel("流程模型的更新 Request VO")
|
||||
@Data
|
||||
public class BpmModelUpdateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1024")
|
||||
@NotEmpty(message = "编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "流程名称", example = "芋道")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "流程描述", example = "我是描述")
|
||||
private String description;
|
||||
|
||||
@ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty(value = "BPMN XML", required = true)
|
||||
private String bpmnXml;
|
||||
|
||||
@ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1")
|
||||
private Integer formType;
|
||||
@ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private Long formId;
|
||||
@ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create",
|
||||
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private String formCustomCreatePath;
|
||||
@ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view",
|
||||
notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空")
|
||||
private String formCustomViewPath;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
public class BpmTaskAssignRuleBaseVO {
|
||||
|
||||
private Integer type;
|
||||
|
||||
private Set<Long> options;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO {
|
||||
|
||||
private String modelId;
|
||||
|
||||
private String taskDefinitionKey;
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String modelId;
|
||||
|
||||
private String processDefinitionId;
|
||||
|
||||
private String taskDefinitionKey;
|
||||
private String taskDefinitionName;
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@ApiModel("用户组精简信息 Response VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmUserGroupSimpleRespVO {
|
||||
|
||||
@ApiModelProperty(value = "用户组编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "用户组名字", required = true, example = "芋道")
|
||||
private String name;
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ApiModel("流程模型的创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmModelCreateReqVO extends BpmModelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "BPMN XML", required = true)
|
||||
@NotEmpty(message = "BPMN XML 不能为空")
|
||||
private String bpmnXml;
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ApiModel("流程模型的更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmModelUpdateReqVO extends BpmModelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1024")
|
||||
@NotEmpty(message = "编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "BPMN XML", required = true)
|
||||
@NotEmpty(message = "BPMN XML 不能为空")
|
||||
private String bpmnXml;
|
||||
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormSimpleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormSimpleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
@ -1,9 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.model;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
@ -11,14 +12,16 @@ import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 流程定义 Convert
|
||||
* 流程模型 Convert
|
||||
*
|
||||
* @author yunlongn
|
||||
*/
|
||||
@ -42,18 +45,15 @@ public interface BpmModelConvert {
|
||||
default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
|
||||
BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
|
||||
modelRespVO.setId(model.getId());
|
||||
modelRespVO.setName(model.getName());
|
||||
modelRespVO.setKey(model.getKey());
|
||||
modelRespVO.setCategory(model.getCategory());
|
||||
modelRespVO.setCreateTime(model.getCreateTime());
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
if (metaInfo != null) {
|
||||
modelRespVO.setDescription(metaInfo.getDescription());
|
||||
}
|
||||
// 通用 copy
|
||||
copyTo(model, modelRespVO);
|
||||
// Form
|
||||
if (form != null) {
|
||||
modelRespVO.setFormId(form.getId());
|
||||
modelRespVO.setFormName(form.getName());
|
||||
}
|
||||
// ProcessDefinition
|
||||
modelRespVO.setProcessDefinition(this.convert(processDefinition));
|
||||
if (modelRespVO.getProcessDefinition() != null) {
|
||||
modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
|
||||
@ -66,49 +66,68 @@ public interface BpmModelConvert {
|
||||
default BpmModelRespVO convert(Model model) {
|
||||
BpmModelRespVO modelRespVO = new BpmModelRespVO();
|
||||
modelRespVO.setId(model.getId());
|
||||
modelRespVO.setName(model.getName());
|
||||
modelRespVO.setKey(model.getKey());
|
||||
modelRespVO.setCategory(model.getCategory());
|
||||
modelRespVO.setCreateTime(model.getCreateTime());
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
if (metaInfo != null) {
|
||||
modelRespVO.setFormId(metaInfo.getFormId());
|
||||
modelRespVO.setDescription(metaInfo.getDescription());
|
||||
}
|
||||
// 通用 copy
|
||||
copyTo(model, modelRespVO);
|
||||
return modelRespVO;
|
||||
}
|
||||
|
||||
default void copyTo(Model model, BpmModelBaseVO to) {
|
||||
to.setName(model.getName());
|
||||
to.setKey(model.getKey());
|
||||
to.setCategory(model.getCategory());
|
||||
// metaInfo
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
copyTo(metaInfo, to);
|
||||
}
|
||||
|
||||
void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);
|
||||
|
||||
default BpmDefinitionCreateReqDTO convert2(Model model) {
|
||||
BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO();
|
||||
createReqDTO.setModelId(model.getId());
|
||||
createReqDTO.setName(model.getName());
|
||||
createReqDTO.setKey(model.getKey());
|
||||
createReqDTO.setCategory(model.getCategory());
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
if (metaInfo != null) {
|
||||
createReqDTO.setDescription(metaInfo.getDescription());
|
||||
createReqDTO.setFormId(metaInfo.getFormId());
|
||||
}
|
||||
// metaInfo
|
||||
copyTo(metaInfo, createReqDTO);
|
||||
return createReqDTO;
|
||||
}
|
||||
|
||||
void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmDefinitionCreateReqDTO to);
|
||||
|
||||
default void copy(Model model, BpmModelCreateReqVO bean) {
|
||||
model.setName(bean.getName());
|
||||
model.setKey(bean.getKey());
|
||||
model.setCategory(bean.getCategory());
|
||||
model.setMetaInfo(JsonUtils.toJsonString(this.buildMetaInfo(bean.getDescription(), bean.getFormId())));
|
||||
model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,
|
||||
null, null));
|
||||
}
|
||||
|
||||
default void copy(Model model, BpmModelUpdateReqVO bean) {
|
||||
model.setName(bean.getName());
|
||||
model.setCategory(bean.getCategory());
|
||||
model.setMetaInfo(JsonUtils.toJsonString(this.buildMetaInfo(bean.getDescription(), bean.getFormId())));
|
||||
model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),
|
||||
bean.getDescription(), bean.getFormType(), bean.getFormId(),
|
||||
bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));
|
||||
}
|
||||
|
||||
default BpmModelMetaInfoRespDTO buildMetaInfo(String description, Long formId) {
|
||||
BpmModelMetaInfoRespDTO metaInfo = new BpmModelMetaInfoRespDTO();
|
||||
metaInfo.setDescription(description);
|
||||
metaInfo.setFormId(formId);
|
||||
return metaInfo;
|
||||
default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType,
|
||||
Long formId, String formCustomCreatePath, String formCustomViewPath) {
|
||||
if (metaInfo == null) {
|
||||
metaInfo = new BpmModelMetaInfoRespDTO();
|
||||
}
|
||||
// 只有非空,才进行设置,避免更新时的覆盖
|
||||
if (StrUtil.isNotEmpty(description)) {
|
||||
metaInfo.setDescription(description);
|
||||
}
|
||||
if (Objects.nonNull(formType)) {
|
||||
metaInfo.setFormType(formType);
|
||||
metaInfo.setFormId(formId);
|
||||
metaInfo.setFormCustomCreatePath(formCustomCreatePath);
|
||||
metaInfo.setFormCustomViewPath(formCustomViewPath);
|
||||
}
|
||||
return JsonUtils.toJsonString(metaInfo);
|
||||
}
|
||||
|
||||
BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
|
@ -1,9 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
@ -11,13 +11,11 @@ import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Bpm 流程定义的 Convert
|
||||
@ -25,9 +23,9 @@ import java.util.function.Function;
|
||||
* @author yunlong.li
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmDefinitionConvert {
|
||||
public interface BpmProcessDefinitionConvert {
|
||||
|
||||
BpmDefinitionConvert INSTANCE = Mappers.getMapper(BpmDefinitionConvert.class);
|
||||
BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
|
||||
|
||||
default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Mapper
|
||||
public interface BpmTaskAssignRuleConvert {
|
||||
|
||||
BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
|
||||
|
||||
default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
|
||||
Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
|
||||
// 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
|
||||
return CollectionUtils.convertList(tasks, task -> {
|
||||
BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
|
||||
if (respVO == null) {
|
||||
respVO = new BpmTaskAssignRuleRespVO();
|
||||
respVO.setTaskDefinitionKey(task.getId());
|
||||
}
|
||||
respVO.setTaskDefinitionName(task.getName());
|
||||
return respVO;
|
||||
});
|
||||
}
|
||||
|
||||
BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
|
||||
|
||||
BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);
|
||||
|
||||
BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
|
||||
|
||||
List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 用户组 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmUserGroupConvert {
|
||||
|
||||
BpmUserGroupConvert INSTANCE = Mappers.getMapper(BpmUserGroupConvert.class);
|
||||
|
||||
BpmUserGroupDO convert(BpmUserGroupCreateReqVO bean);
|
||||
|
||||
BpmUserGroupDO convert(BpmUserGroupUpdateReqVO bean);
|
||||
|
||||
BpmUserGroupRespVO convert(BpmUserGroupDO bean);
|
||||
|
||||
List<BpmUserGroupRespVO> convertList(List<BpmUserGroupDO> list);
|
||||
|
||||
PageResult<BpmUserGroupRespVO> convertPage(PageResult<BpmUserGroupDO> page);
|
||||
|
||||
@Named("convertList2")
|
||||
List<BpmUserGroupRespVO> convertList2(List<BpmUserGroupDO> list);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
@ -1,10 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
|
||||
/**
|
||||
@ -33,6 +33,12 @@ public class BpmProcessDefinitionExtDO extends BaseDO {
|
||||
* 关联 {@link ProcessDefinition#getId()}
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程模型的编号
|
||||
*
|
||||
* 关联 {@link Model#getId()}
|
||||
*/
|
||||
private String modelId;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
@ -0,0 +1,86 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.task.Task;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Bpm 任务分配的规则表,用于自定义配置每个任务的负责人、候选人的分配规则。
|
||||
* 也就是说,废弃 BPMN 原本的 UserTask 设置的 assignee、candidateUsers 等配置,而是通过使用该规则进行计算对应的负责人。
|
||||
*
|
||||
* 1. 默认情况下,{@link #processDefinitionId} 为 {@link #PROCESS_DEFINITION_ID_NULL} 值,表示贵改则与流程模型关联
|
||||
* 2. 在流程模型部署后,会将他的所有规则记录,复制出一份新部署出来的流程定义,通过设置 {@link #processDefinitionId} 为新的流程定义的编号进行关联
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "bpm_task_assign_rule", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmTaskAssignRuleDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
|
||||
*/
|
||||
public static final String PROCESS_DEFINITION_ID_NULL = "";
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 流程模型编号
|
||||
*
|
||||
* 关联 {@link Model#getId()}
|
||||
*/
|
||||
private String modelId;
|
||||
/**
|
||||
* 流程定义编号
|
||||
*
|
||||
* 关联 {@link ProcessDefinition#getId()}
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程任务的定义 Key
|
||||
*
|
||||
* 关联 {@link Task#getTaskDefinitionKey()}
|
||||
*/
|
||||
private String taskDefinitionKey;
|
||||
|
||||
/**
|
||||
* 规则类型
|
||||
*
|
||||
* 枚举 {@link BpmTaskAssignRuleTypeEnum}
|
||||
*/
|
||||
@TableField("`type`")
|
||||
private Integer type;
|
||||
/**
|
||||
* 规则值数组,一般关联指定表的编号
|
||||
* 根据 type 不同,对应的值是不同的:
|
||||
*
|
||||
* 1. {@link BpmTaskAssignRuleTypeEnum#ROLE} 时:角色编号
|
||||
* 2. {@link BpmTaskAssignRuleTypeEnum#DEPT_MEMBER} 时:部门编号
|
||||
* 3. {@link BpmTaskAssignRuleTypeEnum#DEPT_LEADER} 时:部门编号
|
||||
* 4. {@link BpmTaskAssignRuleTypeEnum#USER} 时:用户编号
|
||||
* 5. {@link BpmTaskAssignRuleTypeEnum#USER_GROUP} 时:用户组编号
|
||||
* 6. {@link BpmTaskAssignRuleTypeEnum#SCRIPT} 时:脚本编号,目前通过 {@link BpmTaskRuleScriptEnum#getId()} 标识
|
||||
*/
|
||||
@TableField(typeHandler = JsonLongSetTypeHandler.class)
|
||||
private Set<Long> options;
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
// TODO 芋艿:先埋个坑。任务消息的配置规则。说白了,就是不同的
|
||||
public class BpmTaskMessageRuleDO {
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Bpm 用户组
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "bpm_user_group", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmUserGroupDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 组名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 成员用户编号数组
|
||||
*/
|
||||
@TableField(typeHandler = JsonLongSetTypeHandler.class)
|
||||
private Set<Long> memberUserIds;
|
||||
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO> {
|
||||
|
||||
default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
|
||||
@Nullable String taskDefinitionKey) {
|
||||
return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
|
||||
.eq("process_definition_id", processDefinitionId)
|
||||
.eqIfPresent("task_definition_key", taskDefinitionKey));
|
||||
}
|
||||
|
||||
default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
|
||||
return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
|
||||
.eq("model_id", modelId)
|
||||
.eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
|
||||
}
|
||||
|
||||
default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
|
||||
String taskDefinitionKey) {
|
||||
return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>()
|
||||
.eq("model_id", modelId)
|
||||
.eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
|
||||
.eq("task_definition_key", taskDefinitionKey));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户组 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmUserGroupMapper extends BaseMapperX<BpmUserGroupDO> {
|
||||
|
||||
default PageResult<BpmUserGroupDO> selectPage(BpmUserGroupPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new QueryWrapperX<BpmUserGroupDO>()
|
||||
.likeIfPresent("name", reqVO.getName())
|
||||
.eqIfPresent("status", reqVO.getStatus())
|
||||
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
|
||||
.orderByDesc("id"));
|
||||
}
|
||||
|
||||
default List<BpmUserGroupDO> selectListByStatus(Integer status) {
|
||||
return selectList("status", status);
|
||||
}
|
||||
|
||||
}
|
@ -25,6 +25,9 @@ public interface BpmErrorCodeConstants {
|
||||
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
|
||||
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
|
||||
ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," +
|
||||
"原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
|
||||
|
||||
// ========== 流程定义 1-009-003-000 ==========
|
||||
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||
@ -37,11 +40,22 @@ public interface BpmErrorCodeConstants {
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
|
||||
|
||||
// ========== 流程实例 1-009-005-000 ==========
|
||||
// ========== 流程任务 1-009-005-000 ==========
|
||||
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批");
|
||||
|
||||
// ========== 流程任务分配规则 1-009-006-000 ==========
|
||||
ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则");
|
||||
ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在");
|
||||
ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改");
|
||||
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!");
|
||||
ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在");
|
||||
|
||||
// ========== 动态表单模块 1-009-010-000 ==========
|
||||
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
|
||||
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010000, "表单项({}) 和 ({}) 使用了相同的字段名({})");
|
||||
|
||||
// ========== 用户组模块 1-009-011-000 ==========
|
||||
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在");
|
||||
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用");
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.enums.definition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 模型的表单类型的枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmModelFormTypeEnum {
|
||||
|
||||
NORMAL(10, "流程表单"), // 对应 BpmFormDO
|
||||
CUSTOM(20, "业务表单") // 业务自己定义的表单,自己进行数据的存储
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.enums.definition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 任务分配规则的类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskAssignRuleTypeEnum {
|
||||
|
||||
ROLE(10, "角色"),
|
||||
|
||||
DEPT_MEMBER(20, "部门的成员"), // 包括负责人
|
||||
DEPT_LEADER(21, "部门的负责人"),
|
||||
POST(22, "岗位"),
|
||||
|
||||
USER(30, "用户"),
|
||||
|
||||
USER_GROUP(40, "用户组"),
|
||||
|
||||
SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
|
||||
;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String desc;
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.enums.definition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 任务规则的脚本枚举
|
||||
* 目前暂时通过 TODO 硬编码,未来可以考虑 Groovy 动态脚本的方式
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskRuleScriptEnum {
|
||||
|
||||
ONE(1L, ""),
|
||||
TWO(2L, "");
|
||||
|
||||
/**
|
||||
* 脚本编号
|
||||
*/
|
||||
private final Long id;
|
||||
/**
|
||||
* 脚本描述
|
||||
*/
|
||||
private final String desc;
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener.BpmTackActivitiEventListener;
|
||||
import org.activiti.spring.SpringProcessEngineConfiguration;
|
||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* BPM 模块的 Activiti 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class BpmActivitiConfiguration implements ProcessEngineConfigurationConfigurer {
|
||||
|
||||
@Resource
|
||||
private BpmTackActivitiEventListener taskActivitiEventListener;
|
||||
|
||||
@Override
|
||||
public void configure(SpringProcessEngineConfiguration configuration) {
|
||||
// 注册监听器,例如说 BpmActivitiEventListener
|
||||
configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.activiti.spring.boot.ProcessEngineAutoConfiguration.BEHAVIOR_FACTORY_MAPPING_CONFIGURER;
|
||||
|
||||
/**
|
||||
* BPM 模块的 Activiti 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class BpmActivitiConfiguration {
|
||||
|
||||
/**
|
||||
* BPM 模块的 ProcessEngineConfigurationConfigurer 实现类,主要设置各种监听器
|
||||
*/
|
||||
@Bean
|
||||
public ProcessEngineConfigurationConfigurer bpmProcessEngineConfigurationConfigurer(
|
||||
BpmTackActivitiEventListener taskActivitiEventListener) {
|
||||
return configuration -> {
|
||||
// 注册监听器,例如说 BpmActivitiEventListener
|
||||
configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于设置自定义的 ActivityBehaviorFactory 实现的 ProcessEngineConfigurationConfigurer 实现类
|
||||
*
|
||||
* 目的:覆盖 {@link org.activiti.spring.boot.ProcessEngineAutoConfiguration} 的
|
||||
* defaultActivityBehaviorFactoryMappingConfigurer 方法创建的 Bean
|
||||
*/
|
||||
@Bean(name = BEHAVIOR_FACTORY_MAPPING_CONFIGURER)
|
||||
public ProcessEngineConfigurationConfigurer defaultActivityBehaviorFactoryMappingConfigurer(
|
||||
BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
|
||||
return configuration -> {
|
||||
// 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
|
||||
configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
|
||||
SysPermissionService permissionService,
|
||||
SysDeptService deptService,
|
||||
BpmUserGroupService userGroupService,
|
||||
SysUserService userService,
|
||||
List<BpmTaskAssignScript> scripts) {
|
||||
BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
|
||||
bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
|
||||
bpmActivityBehaviorFactory.setPermissionService(permissionService);
|
||||
bpmActivityBehaviorFactory.setDeptService(deptService);
|
||||
bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
|
||||
bpmActivityBehaviorFactory.setUserService(userService);
|
||||
bpmActivityBehaviorFactory.setScripts(scripts);
|
||||
return bpmActivityBehaviorFactory;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义的 ActivityBehaviorFactory 实现类,目的如下:
|
||||
* 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
|
||||
|
||||
@Setter
|
||||
private BpmTaskAssignRuleService bpmTaskRuleService;
|
||||
@Setter
|
||||
private SysPermissionService permissionService;
|
||||
@Setter
|
||||
private SysDeptService deptService;
|
||||
@Setter
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Setter
|
||||
private SysUserService userService;
|
||||
@Setter
|
||||
private List<BpmTaskAssignScript> scripts;
|
||||
|
||||
@Override
|
||||
public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
|
||||
BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
|
||||
userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
|
||||
userTaskActivityBehavior.setPermissionService(permissionService);
|
||||
userTaskActivityBehavior.setDeptService(deptService);
|
||||
userTaskActivityBehavior.setUserGroupService(userGroupService);
|
||||
userTaskActivityBehavior.setUserService(userService);
|
||||
userTaskActivityBehavior.setScripts(scripts);
|
||||
return userTaskActivityBehavior;
|
||||
}
|
||||
|
||||
// TODO 芋艿:并行任务 ParallelMultiInstanceBehavior
|
||||
|
||||
// TODO 芋艿:并行任务 SequentialMultiInstanceBehavior
|
||||
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.ActivitiException;
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
import org.activiti.engine.impl.el.ExpressionManager;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||
|
||||
/**
|
||||
* 自定义的流程任务的 assignee 负责人的分配
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
|
||||
|
||||
@Setter
|
||||
private BpmTaskAssignRuleService bpmTaskRuleService;
|
||||
@Setter
|
||||
private SysPermissionService permissionService;
|
||||
@Setter
|
||||
private SysDeptService deptService;
|
||||
@Setter
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Setter
|
||||
private SysUserService userService;
|
||||
/**
|
||||
* 任务分配脚本
|
||||
*/
|
||||
private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
|
||||
|
||||
public BpmUserTaskActivitiBehavior(UserTask userTask) {
|
||||
super(userTask);
|
||||
}
|
||||
|
||||
public void setScripts(List<BpmTaskAssignScript> scripts) {
|
||||
this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleAssignments(TaskEntityManager taskEntityManager,
|
||||
String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups,
|
||||
TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {
|
||||
// 获得任务的规则
|
||||
BpmTaskAssignRuleDO rule = getTaskRule(task);
|
||||
// 获得任务的候选用户们
|
||||
Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);
|
||||
// 设置负责人
|
||||
Long assigneeUserId = chooseTaskAssignee(candidateUserIds);
|
||||
taskEntityManager.changeTaskAssignee(task, String.valueOf(assigneeUserId));
|
||||
// 设置候选人们
|
||||
candidateUserIds.remove(assigneeUserId); // 已经成为负责人了,就不要在扮演候选人了
|
||||
if (CollUtil.isNotEmpty(candidateUserIds)) {
|
||||
task.addCandidateUsers(convertSet(candidateUserIds, String::valueOf));
|
||||
}
|
||||
}
|
||||
|
||||
private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) {
|
||||
List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(),
|
||||
task.getTaskDefinitionKey());
|
||||
if (CollUtil.isEmpty(taskRules)) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));
|
||||
}
|
||||
if (taskRules.size() > 1) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));
|
||||
}
|
||||
return taskRules.get(0);
|
||||
}
|
||||
|
||||
private Long chooseTaskAssignee(Set<Long> candidateUserIds) {
|
||||
// TODO 芋艿:未来可以优化下,改成轮询的策略
|
||||
int index = RandomUtil.randomInt(candidateUserIds.size());
|
||||
return CollUtil.get(candidateUserIds, index);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
Set<Long> assigneeUserIds = null;
|
||||
if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);
|
||||
}
|
||||
|
||||
// 移除被禁用的用户
|
||||
removeDisableUsers(assigneeUserIds);
|
||||
// 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));
|
||||
throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
|
||||
}
|
||||
return assigneeUserIds;
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
return permissionService.getUserRoleIdListByRoleIds(rule.getOptions());
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysUserDO> users = userService.getUsersByDeptIds(rule.getOptions());
|
||||
return convertSet(users, SysUserDO::getId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysDeptDO> depts = deptService.getDepts(rule.getOptions());
|
||||
return convertSet(depts, SysDeptDO::getLeaderUserId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<SysUserDO> users = userService.getUsersByPostIds(rule.getOptions());
|
||||
return convertSet(users, SysUserDO::getId);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
return rule.getOptions();
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
|
||||
Set<Long> userIds = new HashSet<>();
|
||||
userGroups.forEach(bpmUserGroupDO -> userIds.addAll(bpmUserGroupDO.getMemberUserIds()));
|
||||
return userIds;
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) {
|
||||
// 获得对应的脚本
|
||||
List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
|
||||
rule.getOptions().forEach(id -> {
|
||||
BpmTaskAssignScript script = scriptMap.get(id);
|
||||
if (script == null) {
|
||||
throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
|
||||
}
|
||||
scripts.add(script);
|
||||
});
|
||||
// 逐个计算任务
|
||||
Set<Long> userIds = new HashSet<>();
|
||||
scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task)));
|
||||
return userIds;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void removeDisableUsers(Set<Long> assigneeUserIds) {
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
return;
|
||||
}
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(assigneeUserIds);
|
||||
assigneeUserIds.removeIf(id -> {
|
||||
SysUserDO user = userMap.get(id);
|
||||
return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* 拓展 {@link org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior} 实现,基于 {@link cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO} 实现自定义的任务分配规则。
|
||||
* 原因:BPMN 默认的 assign、candidateUsers、candidateGroups 拓展起来有一定的难度,所以选择放弃它们,使用自己定义的规则。
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bpm 任务分配的自定义 Script 脚本
|
||||
* 使用场景:
|
||||
* 1. 设置审批人为发起人
|
||||
* 2. 设置审批人为发起人的 Leader
|
||||
* 3. 甚至审批人为发起人的 Leader 的 Leader
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskAssignScript {
|
||||
|
||||
/**
|
||||
* 基于流程任务,获得任务的候选用户们
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 候选人用户的编号数组
|
||||
*/
|
||||
List<Long> calculateTaskCandidateUsers(TaskEntity task);
|
||||
|
||||
/**
|
||||
* 获得枚举值
|
||||
*
|
||||
* @return 枚举值
|
||||
*/
|
||||
BpmTaskRuleScriptEnum getEnum();
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
@ -1,10 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||
import org.activiti.api.model.shared.event.RuntimeEvent;
|
||||
import org.activiti.api.process.model.ProcessInstance;
|
||||
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
|
||||
import org.activiti.api.task.model.Task;
|
||||
import org.activiti.api.task.model.events.TaskRuntimeEvent;
|
||||
import org.activiti.api.task.runtime.events.listener.TaskEventListener;
|
||||
import org.activiti.api.task.runtime.events.listener.TaskRuntimeEventListener;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -16,15 +20,22 @@ import javax.annotation.Resource;
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskEventListener<T extends TaskRuntimeEvent<? extends Task>>
|
||||
implements TaskEventListener<T> {
|
||||
public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>
|
||||
implements TaskRuntimeEventListener<T> {
|
||||
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@Override
|
||||
public void onEvent(T event) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onEvent(T rawEvent) {
|
||||
// 由于 TaskRuntimeEventListener 无法保证只监听 TaskRuntimeEvent 事件,所以通过这样的方式
|
||||
if (!(rawEvent instanceof TaskRuntimeEvent)) {
|
||||
return;
|
||||
}
|
||||
TaskRuntimeEvent<Task> event = (TaskRuntimeEvent<Task>) rawEvent;
|
||||
|
||||
// 创建时,插入拓展表
|
||||
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CREATED) {
|
||||
taskService.createTaskExt(event.getEntity());
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* 自定义各种 Activiti 的监听器,实现流程示例、流程任务的拓展表信息的同步
|
||||
* 例如说,{@link org.activiti.api.task.model.Task} 新建时,我们也要新建对应的 {@link cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO} 记录
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener;
|
@ -1,62 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.config;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import org.activiti.api.runtime.shared.identity.UserGroupManager;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
@Service
|
||||
public class UserGroupManagerService implements UserGroupManager {
|
||||
|
||||
@Resource
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
|
||||
@Resource
|
||||
private SysPostService sysPostService;
|
||||
|
||||
/**
|
||||
* 暂时使用岗位来代替
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getUserGroups(String userId) {
|
||||
// final LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(userId);
|
||||
// final Long id = loginUser.getId();
|
||||
final SysUserDO user = userService.getUserByUsername(userId);
|
||||
return sysPostService.getPosts(user.getPostIds()).stream().map(post -> post.getCode()).collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUserRoles(String userId) {
|
||||
return Arrays.asList("ROLE_ACTIVITI_USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
throw new UnsupportedOperationException("getGroups is now un supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsers() {
|
||||
throw new UnsupportedOperationException("getGroups is now un supported");
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import org.activiti.api.runtime.shared.security.PrincipalGroupsProvider;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserGroupsProvider implements PrincipalGroupsProvider {
|
||||
|
||||
@Override
|
||||
public List<String> getGroups(Principal principal) {
|
||||
|
||||
if(principal instanceof Authentication){
|
||||
Authentication authentication = (Authentication) principal;
|
||||
final Object user = authentication.getPrincipal();
|
||||
if( user instanceof LoginUser){
|
||||
return ((LoginUser) user).getGroups();
|
||||
}else{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}else{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.form;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.activiti.engine.repository.Model;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
@ -1,7 +1,8 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.model;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@ -32,9 +33,10 @@ public interface BpmModelService {
|
||||
* 创建流程模型
|
||||
*
|
||||
* @param modelVO 创建信息
|
||||
* @param bpmnXml BPMN XML
|
||||
* @return 创建的流程模型的编号
|
||||
*/
|
||||
String createModel(@Valid BpmModelCreateReqVO modelVO);
|
||||
String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml);
|
||||
|
||||
/**
|
||||
* 修改流程模型
|
||||
@ -65,4 +67,12 @@ public interface BpmModelService {
|
||||
*/
|
||||
void updateModelState(String id, Integer state);
|
||||
|
||||
/**
|
||||
* 获得流程模型编号对应的 BPMN Model
|
||||
*
|
||||
* @param id 流程模型编号
|
||||
* @return BPMN Model
|
||||
*/
|
||||
BpmnModel getBpmnModel(String id);
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
|
@ -0,0 +1,71 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 任务分配规则 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskAssignRuleService {
|
||||
|
||||
/**
|
||||
* 获得流程定义的任务分配规则数组
|
||||
*
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @param taskDefinitionKey 流程任务定义的 Key。允许空
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
|
||||
@Nullable String taskDefinitionKey);
|
||||
|
||||
/**
|
||||
* 获得流程模型的任务规则数组
|
||||
*
|
||||
* @param modelId 流程模型的编号
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
|
||||
|
||||
/**
|
||||
* 获得流程定义的任务分配规则数组
|
||||
*
|
||||
* @param modelId 流程模型的编号
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);
|
||||
|
||||
/**
|
||||
* 创建任务分配规则
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
* @return 规则编号
|
||||
*/
|
||||
Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 更新任务分配规则
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
*/
|
||||
void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 将流程流程模型的任务分配规则,复制一份给流程定义
|
||||
* 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
|
||||
*
|
||||
* @param fromModelId 流程模型编号
|
||||
* @param toProcessDefinitionId 流程定义编号
|
||||
*/
|
||||
void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
/**
|
||||
* 用户组 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmUserGroupService {
|
||||
|
||||
/**
|
||||
* 创建用户组
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createUserGroup(@Valid BpmUserGroupCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新用户组
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateUserGroup(@Valid BpmUserGroupUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除用户组
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteUserGroup(Long id);
|
||||
|
||||
/**
|
||||
* 获得用户组
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 用户组
|
||||
*/
|
||||
BpmUserGroupDO getUserGroup(Long id);
|
||||
|
||||
/**
|
||||
* 获得用户组列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 用户组列表
|
||||
*/
|
||||
List<BpmUserGroupDO> getUserGroupList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得指定状态的用户组列表
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 用户组列表
|
||||
*/
|
||||
List<BpmUserGroupDO> getUserGroupListByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 获得用户组分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 用户组分页
|
||||
*/
|
||||
PageResult<BpmUserGroupDO> getUserGroupPage(BpmUserGroupPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 校验用户组们是否有效。如下情况,视为无效:
|
||||
* 1. 用户组编号不存在
|
||||
* 2. 用户组被禁用
|
||||
*
|
||||
* @param ids 用户组编号数组
|
||||
*/
|
||||
void validUserGroups(Set<Long> ids);
|
||||
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 流程定义创建 Request DTO
|
||||
@ -10,6 +12,13 @@ import javax.validation.constraints.NotEmpty;
|
||||
@Data
|
||||
public class BpmDefinitionCreateReqDTO {
|
||||
|
||||
// ========== 模型相关 ==========
|
||||
|
||||
/**
|
||||
* 流程模型的编号
|
||||
*/
|
||||
@NotEmpty(message = "流程模型编号不能为空")
|
||||
private String modelId;
|
||||
/**
|
||||
* 流程标识
|
||||
*/
|
||||
@ -35,9 +44,30 @@ public class BpmDefinitionCreateReqDTO {
|
||||
*/
|
||||
@NotEmpty(message = "BPMN XML 不能为空")
|
||||
private String bpmnXml;
|
||||
|
||||
// ========== 表单相关 ==========
|
||||
|
||||
/**
|
||||
* 动态表单编号,允许空
|
||||
* 表单类型
|
||||
*/
|
||||
@NotNull(message = "表单类型不能为空")
|
||||
private Integer formType;
|
||||
/**
|
||||
* 动态表单编号
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
|
||||
*/
|
||||
private Long formId;
|
||||
/**
|
||||
* 自定义表单的提交路径,使用 Vue 的路由地址
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||
*/
|
||||
private String formCustomCreatePath;
|
||||
/**
|
||||
* 自定义表单的查看路径,使用 Vue 的路由地址
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||
*/
|
||||
private String formCustomViewPath;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.form.dto;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* BPM 流程 MetaInfo Response DTO
|
||||
* 主要用于 {@link org.activiti.engine.repository.Model#setMetaInfo(String)} 的存储
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class BpmModelMetaInfoRespDTO {
|
||||
|
||||
/**
|
||||
* 流程描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 表单类型
|
||||
*/
|
||||
private Integer formType;
|
||||
/**
|
||||
* 表单编号
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
|
||||
*/
|
||||
private Long formId;
|
||||
/**
|
||||
* 自定义表单的提交路径,使用 Vue 的路由地址
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||
*/
|
||||
private String formCustomCreatePath;
|
||||
/**
|
||||
* 自定义表单的查看路径,使用 Vue 的路由地址
|
||||
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||
*/
|
||||
private String formCustomViewPath;
|
||||
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.form.impl;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form.BpmFormMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.form.dto.BpmFormFieldRespDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmFormConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmFormMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmFormFieldRespDTO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import org.springframework.stereotype.Service;
|
@ -1,26 +1,35 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.model.impl;
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.model.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.model.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.converter.BpmnXMLConverter;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.impl.persistence.entity.SuspensionState;
|
||||
import org.activiti.engine.impl.util.io.StringStreamSource;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ModelQuery;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@ -31,9 +40,11 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
@ -50,9 +61,12 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
@Resource
|
||||
private BpmFormService bpmFormService;
|
||||
private BpmFormService formService;
|
||||
@Resource
|
||||
private BpmProcessDefinitionService bpmProcessDefinitionService;
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskAssignRuleService taskAssignRuleService;
|
||||
|
||||
@Override
|
||||
public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
|
||||
@ -75,14 +89,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
return metaInfo != null ? metaInfo.getFormId() : null;
|
||||
});
|
||||
Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
|
||||
Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
|
||||
|
||||
// 获得 Deployment Map
|
||||
Set<String> deploymentIds = new HashSet<>();
|
||||
models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
|
||||
Map<String, Deployment> deploymentMap = bpmProcessDefinitionService.getDeploymentMap(deploymentIds);
|
||||
Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
|
||||
// 获得 ProcessDefinition Map
|
||||
List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
|
||||
List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
|
||||
Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
|
||||
|
||||
// 拼接结果
|
||||
@ -105,7 +119,7 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public String createModel(BpmModelCreateReqVO createReqVO) {
|
||||
public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {
|
||||
checkKeyNCName(createReqVO.getKey());
|
||||
// 校验流程标识已经存在
|
||||
Model keyModel = this.getModelByKey(createReqVO.getKey());
|
||||
@ -118,15 +132,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
BpmModelConvert.INSTANCE.copy(model, createReqVO);
|
||||
// 保存流程定义
|
||||
repositoryService.saveModel(model);
|
||||
// 添加 BPMN XML
|
||||
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(createReqVO.getBpmnXml()));
|
||||
// 保存 BPMN XML
|
||||
saveModelBpmnXml(model, bpmnXml);
|
||||
return model.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
||||
public void updateModel(BpmModelUpdateReqVO updateReqVO) {
|
||||
checkKeyNCName(updateReqVO.getKey());
|
||||
// 校验流程模型存在
|
||||
Model model = repositoryService.getModel(updateReqVO.getId());
|
||||
if (model == null) {
|
||||
@ -138,7 +151,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
// 更新模型
|
||||
repositoryService.saveModel(model);
|
||||
// 更新 BPMN XML
|
||||
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(updateReqVO.getBpmnXml()));
|
||||
saveModelBpmnXml(model, updateReqVO.getBpmnXml());
|
||||
}
|
||||
|
||||
private void saveModelBpmnXml(Model model, String bpmnXml) {
|
||||
if (StrUtil.isEmpty(bpmnXml)) {
|
||||
return;
|
||||
}
|
||||
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -149,28 +169,60 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
if (ObjectUtils.isEmpty(model)) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// 校验流程图
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
|
||||
if (bpmnBytes == null) {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
|
||||
// 校验表单已配
|
||||
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
||||
if (metaInfo == null || metaInfo.getFormType() == null) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
|
||||
}
|
||||
// 校验任务分配规则已配置
|
||||
checkTaskAssignRuleAllConfig(id);
|
||||
|
||||
// 创建流程定义
|
||||
BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model)
|
||||
.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
|
||||
String definitionId = bpmProcessDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
||||
String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
||||
|
||||
// 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
|
||||
if (StrUtil.isNotEmpty(model.getDeploymentId())) {
|
||||
ProcessDefinition oldDefinition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
if (oldDefinition != null) {
|
||||
bpmProcessDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
|
||||
processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
|
||||
}
|
||||
}
|
||||
|
||||
// 更新 model 的 deploymentId,进行关联
|
||||
ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinition(definitionId);
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
|
||||
model.setDeploymentId(definition.getDeploymentId());
|
||||
repositoryService.saveModel(model);
|
||||
|
||||
// 复制任务分配规则
|
||||
taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验流程模型的任务分配规则全部都配置了
|
||||
* 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
|
||||
*
|
||||
* @param id 流程模型编号
|
||||
*/
|
||||
private void checkTaskAssignRuleAllConfig(String id) {
|
||||
// 一个用户任务都没配置,所以无需配置规则
|
||||
List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
|
||||
if (CollUtil.isEmpty(taskAssignRules)) {
|
||||
return;
|
||||
}
|
||||
// 校验未配置规则的任务
|
||||
taskAssignRules.forEach(rule -> {
|
||||
if (CollUtil.isEmpty(rule.getOptions())) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -192,13 +244,22 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
throw exception(MODEL_NOT_EXISTS);
|
||||
}
|
||||
// 校验流程定义存在
|
||||
ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
||||
if (definition == null) {
|
||||
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
bpmProcessDefinitionService.updateProcessDefinitionState(definition.getId(), state);
|
||||
processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmnModel getBpmnModel(String id) {
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
|
||||
if (ArrayUtil.isEmpty(bpmnBytes)) {
|
||||
return null;
|
||||
}
|
||||
return ActivitiUtils.buildBpmnModel(bpmnBytes);
|
||||
}
|
||||
|
||||
private Model getModelByKey(String key) {
|
||||
@ -211,4 +272,10 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 创建转换对象
|
||||
BpmnXMLConverter converter = new BpmnXMLConverter();
|
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(new StringStreamSource(""), true, true);
|
||||
}
|
||||
|
||||
}
|
@ -2,17 +2,17 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmDefinitionConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmProcessDefinitionConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
@ -90,7 +90,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
|
||||
// 拼接结果
|
||||
long definitionCount = definitionQuery.count();
|
||||
return new PageResult<>(BpmDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
|
||||
return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
|
||||
processDefinitionDOMap, formMap), definitionCount);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs,
|
||||
BpmProcessDefinitionExtDO::getProcessDefinitionId);
|
||||
// 执行查询,并返回
|
||||
return BpmDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
|
||||
return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,6 +121,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
if (bpmnModel == null) {
|
||||
return null;
|
||||
}
|
||||
// TODO 芋艿:重构到 activi util 里
|
||||
byte[] bpmnBytes = BPMN_XML_CONVERTER.convertToXML(bpmnModel);
|
||||
return StrUtil.utf8Str(bpmnBytes);
|
||||
}
|
||||
@ -179,7 +180,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
// 创建 Deployment 部署
|
||||
Deployment deploy = repositoryService.createDeployment()
|
||||
.key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
|
||||
.addString(createReqDTO.getName() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
|
||||
.addString(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
|
||||
.deploy();
|
||||
|
||||
// 设置 ProcessDefinition 的 category 分类
|
||||
@ -196,7 +197,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
}
|
||||
|
||||
// 插入拓展表
|
||||
BpmProcessDefinitionExtDO definitionDO = BpmDefinitionConvert.INSTANCE.convert2(createReqDTO)
|
||||
BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)
|
||||
.setProcessDefinitionId(definition.getId());
|
||||
processDefinitionMapper.insert(definitionDO);
|
||||
return definition.getId();
|
||||
@ -206,12 +207,14 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
public void updateProcessDefinitionState(String id, Integer state) {
|
||||
// 激活
|
||||
if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
|
||||
repositoryService.activateProcessDefinitionById(id, true, null);
|
||||
repositoryService.activateProcessDefinitionById(id, false, null);
|
||||
return;
|
||||
}
|
||||
// 挂起
|
||||
if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
|
||||
repositoryService.suspendProcessDefinitionById(id, true, null);
|
||||
// suspendProcessInstances = false,进行中的任务,不进行挂起。
|
||||
// 原因:只要新的流程不允许发起即可,老流程继续可以执行。
|
||||
repositoryService.suspendProcessDefinitionById(id, false, null);
|
||||
return;
|
||||
}
|
||||
log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
|
||||
|
@ -0,0 +1,178 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmTaskAssignRuleConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dict.SysDictDataService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants.BPM_TASK_ASSIGN_RULE_TYPE;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* BPM 任务分配规则 Service 实现类
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
|
||||
@Resource
|
||||
private BpmTaskAssignRuleMapper taskRuleMapper;
|
||||
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmModelService modelService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
@Resource
|
||||
private SysRoleService roleService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
@Resource
|
||||
private SysPostService postService;
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private BpmUserGroupService userGroupService;
|
||||
@Resource
|
||||
private SysDictDataService dictDataService;
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
|
||||
String taskDefinitionKey) {
|
||||
return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {
|
||||
return taskRuleMapper.selectListByModelId(modelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {
|
||||
// 获得规则
|
||||
List<BpmTaskAssignRuleDO> rules = Collections.emptyList();
|
||||
BpmnModel model = null;
|
||||
if (StrUtil.isNotEmpty(modelId)) {
|
||||
rules = getTaskAssignRuleListByModelId(modelId);
|
||||
model = modelService.getBpmnModel(modelId);
|
||||
} else if (StrUtil.isNotEmpty(processDefinitionId)) {
|
||||
rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);
|
||||
model = processDefinitionService.getBpmnModel(processDefinitionId);
|
||||
}
|
||||
if (model == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 获得用户任务,只有用户任务才可以设置分配规则
|
||||
List<UserTask> userTasks = ActivitiUtils.getBpmnModelElements(model, UserTask.class);
|
||||
if (CollUtil.isEmpty(userTasks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 转换数据
|
||||
return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createTaskAssignRule(BpmTaskAssignRuleCreateReqVO reqVO) {
|
||||
// 校验参数
|
||||
validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
|
||||
// 校验是否已经配置
|
||||
BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(
|
||||
reqVO.getModelId(), reqVO.getTaskDefinitionKey());
|
||||
if (existRule != null) {
|
||||
throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
|
||||
}
|
||||
|
||||
// 存储
|
||||
BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
|
||||
.setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
|
||||
taskRuleMapper.insert(rule);
|
||||
return rule.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskAssignRule(BpmTaskAssignRuleUpdateReqVO reqVO) {
|
||||
// 校验参数
|
||||
validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
|
||||
// 校验是否存在
|
||||
BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId());
|
||||
if (existRule == null) {
|
||||
throw exception(TASK_ASSIGN_RULE_NOT_EXISTS);
|
||||
}
|
||||
// 只允许修改流程模型的规则
|
||||
if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) {
|
||||
throw exception(TASK_UPDATE_FAIL_NOT_MODEL);
|
||||
}
|
||||
|
||||
// 执行更新
|
||||
taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
|
||||
List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
|
||||
if (CollUtil.isEmpty(rules)) {
|
||||
return;
|
||||
}
|
||||
// 开始复制
|
||||
List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
|
||||
newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
|
||||
.setCreateTime(null).setUpdateTime(null));
|
||||
taskRuleMapper.insertBatch(newRules);
|
||||
}
|
||||
|
||||
private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
|
||||
if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
|
||||
roleService.validRoles(options);
|
||||
} else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
|
||||
BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
|
||||
deptService.validDepts(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {
|
||||
postService.validPosts(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) {
|
||||
userService.validUsers(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) {
|
||||
userGroupService.validUserGroups(options);
|
||||
} else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {
|
||||
dictDataService.validDictDatas(SysDictTypeConstants.BPM_TASK_ASSIGN_SCRIPT,
|
||||
CollectionUtils.convertSet(options, String::valueOf));
|
||||
} else {
|
||||
throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmUserGroupConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmUserGroupMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.USER_GROUP_IS_DISABLE;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.USER_GROUP_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.USER_IS_DISABLE;
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.USER_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* 用户组 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmUserGroupServiceImpl implements BpmUserGroupService {
|
||||
|
||||
@Resource
|
||||
private BpmUserGroupMapper userGroupMapper;
|
||||
|
||||
@Override
|
||||
public Long createUserGroup(BpmUserGroupCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
BpmUserGroupDO userGroup = BpmUserGroupConvert.INSTANCE.convert(createReqVO);
|
||||
userGroupMapper.insert(userGroup);
|
||||
// 返回
|
||||
return userGroup.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserGroup(BpmUserGroupUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
this.validateUserGroupExists(updateReqVO.getId());
|
||||
// 更新
|
||||
BpmUserGroupDO updateObj = BpmUserGroupConvert.INSTANCE.convert(updateReqVO);
|
||||
userGroupMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUserGroup(Long id) {
|
||||
// 校验存在
|
||||
this.validateUserGroupExists(id);
|
||||
// 删除
|
||||
userGroupMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateUserGroupExists(Long id) {
|
||||
if (userGroupMapper.selectById(id) == null) {
|
||||
throw exception(USER_GROUP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmUserGroupDO getUserGroup(Long id) {
|
||||
return userGroupMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmUserGroupDO> getUserGroupList(Collection<Long> ids) {
|
||||
return userGroupMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmUserGroupDO> getUserGroupListByStatus(Integer status) {
|
||||
return userGroupMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmUserGroupDO> getUserGroupPage(BpmUserGroupPageReqVO pageReqVO) {
|
||||
return userGroupMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validUserGroups(Set<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得用户组信息
|
||||
List<BpmUserGroupDO> userGroups = userGroupMapper.selectBatchIds(ids);
|
||||
Map<Long, BpmUserGroupDO> userGroupMap = CollectionUtils.convertMap(userGroups, BpmUserGroupDO::getId);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
BpmUserGroupDO userGroup = userGroupMap.get(id);
|
||||
if (userGroup == null) {
|
||||
throw exception(USER_GROUP_NOT_EXISTS);
|
||||
}
|
||||
if (!CommonStatusEnum.ENABLE.getStatus().equals(userGroup.getStatus())) {
|
||||
throw exception(USER_GROUP_IS_DISABLE, userGroup.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* BPM 流程 MetaInfo Response DTO
|
||||
* 主要用于 {@link org.activiti.engine.repository.Model#setMetaInfo(String)} 的存储
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class BpmModelMetaInfoRespDTO {
|
||||
|
||||
/**
|
||||
* 流程描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 表单编号
|
||||
*/
|
||||
private Long formId;
|
||||
|
||||
}
|
@ -87,8 +87,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
|
||||
|
||||
// TODO 芋艿:临时使用, 保证分配
|
||||
List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId());
|
||||
tasks.forEach(task -> taskService.updateTaskAssign(task.getId(), userId));
|
||||
// List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId());
|
||||
// tasks.forEach(task -> taskService.updateTaskAssign(task.getId(), userId));
|
||||
|
||||
// 添加初始的评论 TODO 芋艿:在思考下
|
||||
// Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ -28,8 +30,8 @@ public class SysDeptBaseVO {
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@ApiModelProperty(value = "负责人", example = "芋道")
|
||||
private String leader;
|
||||
@ApiModelProperty(value = "负责人的用户编号", example = "2048")
|
||||
private Long leaderUserId;
|
||||
|
||||
@ApiModelProperty(value = "联系电话", example = "15601691000")
|
||||
@Size(max = 11, message = "联系电话长度不能超过11个字符")
|
||||
@ -42,7 +44,7 @@ public class SysDeptBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
|
||||
@NotNull(message = "状态不能为空")
|
||||
// @InEnum(value = SysCommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
// @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public class SysPermissionController {
|
||||
@GetMapping("/list-user-roles")
|
||||
// @RequiresPermissions("system:permission:assign-user-role")
|
||||
public CommonResult<Set<Long>> listAdminRoles(@RequestParam("userId") Long userId) {
|
||||
return success(permissionService.listUserRoleIs(userId));
|
||||
return success(permissionService.getUserRoleIdListByUserId(userId));
|
||||
}
|
||||
|
||||
@ApiOperation("赋予用户角色")
|
||||
|
@ -97,7 +97,7 @@ public class SysRoleController {
|
||||
@OperateLog(type = EXPORT)
|
||||
@PreAuthorize("@ss.hasPermission('system:role:export')")
|
||||
public void export(HttpServletResponse response, @Validated SysRoleExportReqVO reqVO) throws IOException {
|
||||
List<SysRoleDO> list = roleService.getRoles(reqVO);
|
||||
List<SysRoleDO> list = roleService.getRoleList(reqVO);
|
||||
List<SysRoleExcelVO> data = SysRoleConvert.INSTANCE.convertList03(list);
|
||||
// 输出
|
||||
ExcelUtils.write(response, "角色数据.xls", "角色列表", SysRoleExcelVO.class, data);
|
||||
|
@ -1,7 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.controller.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept.SysDeptSimpleRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.convert.dept.SysDeptConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.convert.user.SysUserConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
|
||||
@ -32,6 +35,8 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Api(tags = "用户")
|
||||
@ -99,7 +104,7 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
// 获得拼接需要的数据
|
||||
Collection<Long> deptIds = CollectionUtils.convertList(pageResult.getList(), SysUserDO::getDeptId);
|
||||
Collection<Long> deptIds = convertList(pageResult.getList(), SysUserDO::getDeptId);
|
||||
Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(deptIds);
|
||||
// 拼接结果返回
|
||||
List<SysUserPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size());
|
||||
@ -111,6 +116,15 @@ public class SysUserController {
|
||||
return success(new PageResult<>(userList, pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/list-all-simple")
|
||||
@ApiOperation(value = "获取用户精简信息列表", notes = "只包含被开启的用户,主要用于前端的下拉选项")
|
||||
public CommonResult<List<SysUserSimpleRespVO>> getSimpleUsers() {
|
||||
// 获用户门列表,只要开启状态的
|
||||
List<SysUserDO> list = userService.getUsersByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// 排序后,返回给前端
|
||||
return success(SysUserConvert.INSTANCE.convertList04(list));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得用户详情")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@ -129,15 +143,19 @@ public class SysUserController {
|
||||
List<SysUserDO> users = userService.getUsers(reqVO);
|
||||
|
||||
// 获得拼接需要的数据
|
||||
Collection<Long> deptIds = CollectionUtils.convertList(users, SysUserDO::getDeptId);
|
||||
Collection<Long> deptIds = convertList(users, SysUserDO::getDeptId);
|
||||
Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(deptIds);
|
||||
Map<Long, SysUserDO> deptLeaderUserMap = userService.getUserMap(convertSet(deptMap.values(), SysDeptDO::getLeaderUserId));
|
||||
// 拼接数据
|
||||
List<SysUserExcelVO> excelUsers = new ArrayList<>(users.size());
|
||||
users.forEach(user -> {
|
||||
SysUserExcelVO excelVO = SysUserConvert.INSTANCE.convert02(user);
|
||||
// 设置部门
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> {
|
||||
excelVO.setDeptName(dept.getName());
|
||||
excelVO.setDeptLeader(dept.getLeader());
|
||||
// 设置部门负责人的名字
|
||||
MapUtils.findAndThen(deptLeaderUserMap, dept.getLeaderUserId(),
|
||||
deptLeaderUser -> excelVO.setDeptLeaderNickname(deptLeaderUser.getNickname()));
|
||||
});
|
||||
excelUsers.add(excelVO);
|
||||
});
|
||||
|
@ -65,7 +65,7 @@ public class SysUserProfileController {
|
||||
SysUserDO user = userCoreService.getUser(getLoginUserId());
|
||||
SysUserProfileRespVO resp = SysUserConvert.INSTANCE.convert03(user);
|
||||
// 获得用户角色
|
||||
List<SysRoleDO> userRoles = roleService.getRolesFromCache(permissionService.listUserRoleIs(user.getId()));
|
||||
List<SysRoleDO> userRoles = roleService.getRolesFromCache(permissionService.getUserRoleIdListByUserId(user.getId()));
|
||||
resp.setRoles(SysUserConvert.INSTANCE.convertList(userRoles));
|
||||
// 获得部门信息
|
||||
if (user.getDeptId() != null) {
|
||||
|
@ -47,6 +47,6 @@ public class SysUserExcelVO {
|
||||
private String deptName;
|
||||
|
||||
@ExcelProperty("部门负责人")
|
||||
private String deptLeader;
|
||||
private String deptLeaderNickname;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@ApiModel("用户精简信息 Response VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserSimpleRespVO {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "用户昵称", required = true, example = "芋道")
|
||||
private String nickname;
|
||||
|
||||
}
|
@ -45,4 +45,5 @@ public interface SysUserConvert {
|
||||
|
||||
List<SysUserProfileRespVO.SocialUser> convertList03(List<SysSocialUserDO> list);
|
||||
|
||||
List<SysUserSimpleRespVO> convertList04(List<SysUserDO> list);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@ -11,6 +12,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 部门表
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("sys_dept")
|
||||
@Data
|
||||
@ -38,8 +40,10 @@ public class SysDeptDO extends TenantBaseDO {
|
||||
private Integer sort;
|
||||
/**
|
||||
* 负责人
|
||||
*
|
||||
* 关联 {@link SysUserDO#getId()}
|
||||
*/
|
||||
private String leader;
|
||||
private Long leaderUserId;
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
|
@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -20,6 +21,11 @@ public interface SysDictDataMapper extends BaseMapperX<SysDictDataDO> {
|
||||
.eq("value", value));
|
||||
}
|
||||
|
||||
default List<SysDictDataDO> selectByDictTypeAndValues(String dictType, Collection<String> values) {
|
||||
return selectList(new QueryWrapper<SysDictDataDO>().eq("dict_type", dictType)
|
||||
.in("value", values));
|
||||
}
|
||||
|
||||
default int selectCountByDictType(String dictType) {
|
||||
return selectCount("dict_type", dictType);
|
||||
}
|
||||
|
@ -16,6 +16,14 @@ public interface SysUserRoleMapper extends BaseMapperX<SysUserRoleDO> {
|
||||
return selectList(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
|
||||
}
|
||||
|
||||
default List<SysUserRoleDO> selectListByRoleId(Long roleId) {
|
||||
return selectList(new QueryWrapper<SysUserRoleDO>().eq("role_id", roleId));
|
||||
}
|
||||
|
||||
default List<SysUserRoleDO> selectListByRoleIds(Collection<Long> roleIds) {
|
||||
return selectList("role_id", roleIds);
|
||||
}
|
||||
|
||||
default void insertList(Long userId, Collection<Long> roleIds) {
|
||||
List<SysUserRoleDO> list = roleIds.stream().map(roleId -> {
|
||||
SysUserRoleDO entity = new SysUserRoleDO();
|
||||
@ -23,8 +31,7 @@ public interface SysUserRoleMapper extends BaseMapperX<SysUserRoleDO> {
|
||||
entity.setRoleId(roleId);
|
||||
return entity;
|
||||
}).collect(Collectors.toList());
|
||||
// TODO 芋艿,mybatis plus 增加批量插入的功能
|
||||
list.forEach(this::insert);
|
||||
insertBatch(list);
|
||||
}
|
||||
|
||||
default void deleteListByUserIdAndRoleIdIds(Long userId, Collection<Long> roleIds) {
|
||||
|
@ -55,7 +55,7 @@ public interface SysUserMapper extends BaseMapperX<SysUserDO> {
|
||||
return selectList(new QueryWrapperX<SysUserDO>().like("username", username));
|
||||
}
|
||||
|
||||
|
||||
// TODO 芋艿:可废弃该方法
|
||||
default List<SysUserDO> selectListByDepartIdAndPostId(Long departId, Long postId) {
|
||||
return selectList(new QueryWrapperX<SysUserDO>()
|
||||
.eq("status", CommonStatusEnum.ENABLE.getStatus())
|
||||
@ -64,5 +64,13 @@ public interface SysUserMapper extends BaseMapperX<SysUserDO> {
|
||||
.likeIfPresent("post_ids", Optional.ofNullable(postId).map(t -> String.valueOf(postId)).orElse("")));
|
||||
}
|
||||
|
||||
default List<SysUserDO> selectListByStatus(Integer status) {
|
||||
return selectList("status", status);
|
||||
}
|
||||
|
||||
default List<SysUserDO> selectListByDeptIds(Collection<Long> deptIds) {
|
||||
return selectList("dept_id", deptIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,4 +22,7 @@ public interface SysDictTypeConstants {
|
||||
String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态
|
||||
String SMS_RECEIVE_STATUS = "sys_sms_receive_status"; // 短信接收状态
|
||||
|
||||
String BPM_TASK_ASSIGN_RULE_TYPE = "bpm_task_assign_rule_type"; // 任务分配规则类型
|
||||
String BPM_TASK_ASSIGN_SCRIPT = "bpm_task_assign_script"; // 任务分配自定义脚本
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public interface SysErrorCodeConstants {
|
||||
ErrorCode ROLE_NAME_DUPLICATE = new ErrorCode(1002003001, "已经存在名为【{}】的角色");
|
||||
ErrorCode ROLE_CODE_DUPLICATE = new ErrorCode(1002003002, "已经存在编码为【{}】的角色");
|
||||
ErrorCode ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE = new ErrorCode(1002003004, "不能操作类型为系统内置的角色");
|
||||
ErrorCode ROLE_IS_DISABLE = new ErrorCode(1002003004, "名字为【{}】的角色已被禁用");
|
||||
|
||||
// ========== 用户模块 1002004000 ==========
|
||||
ErrorCode USER_USERNAME_EXISTS = new ErrorCode(1002004000, "用户账号已经存在");
|
||||
@ -39,6 +40,7 @@ public interface SysErrorCodeConstants {
|
||||
ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在");
|
||||
ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!");
|
||||
ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败");
|
||||
ErrorCode USER_IS_DISABLE = new ErrorCode(1002003004, "名字为【{}】的用户已被禁用");
|
||||
|
||||
// ========== 部门模块 1002005000 ==========
|
||||
ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门");
|
||||
@ -65,7 +67,7 @@ public interface SysErrorCodeConstants {
|
||||
|
||||
// ========== 字典数据 1002007000 ==========
|
||||
ErrorCode DICT_DATA_NOT_EXISTS = new ErrorCode(1002007001, "当前字典数据不存在");
|
||||
ErrorCode DICT_DATA_NOT_ENABLE = new ErrorCode(1002007002, "字典数据不处于开启状态,不允许选择");
|
||||
ErrorCode DICT_DATA_NOT_ENABLE = new ErrorCode(1002007002, "字典数据({})不处于开启状态,不允许选择");
|
||||
ErrorCode DICT_DATA_VALUE_DUPLICATE = new ErrorCode(1002007003, "已经存在该值的字典数据");
|
||||
|
||||
// ========== 通知公告 1002008000 ==========
|
||||
|
@ -84,6 +84,14 @@ public interface SysDeptService {
|
||||
*/
|
||||
SysDeptDO getDept(Long id);
|
||||
|
||||
/**
|
||||
* 获得部门信息数组
|
||||
*
|
||||
* @param ids 部门编号数组
|
||||
* @return 部门信息数组
|
||||
*/
|
||||
List<SysDeptDO> getDepts(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得所有子部门,从缓存中
|
||||
*
|
||||
@ -93,4 +101,13 @@ public interface SysDeptService {
|
||||
*/
|
||||
List<SysDeptDO> getDeptsByParentIdFromCache(Long parentId, boolean recursive);
|
||||
|
||||
/**
|
||||
* 校验部门们是否有效。如下情况,视为无效:
|
||||
* 1. 部门编号不存在
|
||||
* 2. 部门被禁用
|
||||
*
|
||||
* @param ids 角色编号数组
|
||||
*/
|
||||
void validDepts(Collection<Long> ids);
|
||||
|
||||
}
|
||||
|
@ -86,4 +86,13 @@ public interface SysPostService {
|
||||
*/
|
||||
SysPostDO getPost(Long id);
|
||||
|
||||
/**
|
||||
* 校验岗位们是否有效。如下情况,视为无效:
|
||||
* 1. 岗位编号不存在
|
||||
* 2. 岗位被禁用
|
||||
*
|
||||
* @param ids 岗位编号数组
|
||||
*/
|
||||
void validPosts(Collection<Long> ids);
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.service.dept.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept.SysDeptCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
|
||||
@ -26,6 +27,7 @@ import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* 部门 Service 实现类
|
||||
@ -180,6 +182,26 @@ public class SysDeptServiceImpl implements SysDeptService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validDepts(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得科室信息
|
||||
List<SysDeptDO> depts = deptMapper.selectBatchIds(ids);
|
||||
Map<Long, SysDeptDO> deptMap = CollectionUtils.convertMap(depts, SysDeptDO::getId);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
SysDeptDO dept = deptMap.get(id);
|
||||
if (dept == null) {
|
||||
throw exception(DEPT_NOT_FOUND);
|
||||
}
|
||||
if (!CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) {
|
||||
throw exception(DEPT_NOT_ENABLE, dept.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取所有的子部门,添加到 result 结果
|
||||
*
|
||||
@ -210,6 +232,11 @@ public class SysDeptServiceImpl implements SysDeptService {
|
||||
return deptMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDeptDO> getDepts(Collection<Long> ids) {
|
||||
return deptMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
private void checkCreateOrUpdate(Long id, Long parentId, String name) {
|
||||
// 校验自己存在
|
||||
checkDeptExists(id);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user