diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java index b09230a7..4aabcf3d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java @@ -5,8 +5,11 @@ import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.workflow.domain.bo.WfCopyBo; +import com.ruoyi.workflow.domain.vo.WfCopyVo; import com.ruoyi.workflow.domain.vo.WfDefinitionVo; import com.ruoyi.workflow.domain.vo.WfTaskVo; +import com.ruoyi.workflow.service.IWfCopyService; import com.ruoyi.workflow.service.IWfProcessService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -31,6 +34,7 @@ import java.util.Map; public class WfProcessController extends BaseController { private final IWfProcessService processService; + private final IWfCopyService copyService; @GetMapping(value = "/list") @SaCheckPermission("workflow:process:startList") @@ -69,4 +73,12 @@ public class WfProcessController extends BaseController { public TableDataInfo finishedProcess(PageQuery pageQuery) { return processService.queryPageFinishedProcessList(pageQuery); } + + @ApiOperation(value = "获取抄送列表", response = WfTaskVo.class) + @SaCheckPermission("workflow:process:copyList") + @GetMapping(value = "/copyList") + public TableDataInfo copyProcess(WfCopyBo copyBo, PageQuery pageQuery) { + copyBo.setUserId(getUserId()); + return copyService.queryPageList(copyBo, pageQuery); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/WfCopy.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/WfCopy.java new file mode 100644 index 00000000..f59accd3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/WfCopy.java @@ -0,0 +1,74 @@ +package com.ruoyi.workflow.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 流程抄送对象 wf_copy + * + * @author KonBAI + * @date 2022-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("wf_copy") +public class WfCopy extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 抄送主键 + */ + @TableId(value = "copy_id") + private Long copyId; + /** + * 抄送标题 + */ + private String title; + /** + * 流程主键 + */ + private String processId; + /** + * 流程名称 + */ + private String processName; + /** + * 流程分类主键 + */ + private String categoryId; + /** + * 部署主键 + */ + private String deploymentId; + /** + * 流程实例主键 + */ + private String instanceId; + /** + * 任务主键 + */ + private String taskId; + /** + * 用户主键 + */ + private Long userId; + /** + * 发起人Id + */ + private Long originatorId; + /** + * 发起人名称 + */ + private String originatorName; + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableLogic + private String delFlag; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfCopyBo.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfCopyBo.java new file mode 100644 index 00000000..9f6a317b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfCopyBo.java @@ -0,0 +1,87 @@ +package com.ruoyi.workflow.domain.bo; + +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 流程抄送业务对象 wf_copy + * + * @author ruoyi + * @date 2022-05-19 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel("流程抄送业务对象") +public class WfCopyBo extends BaseEntity { + + /** + * 抄送主键 + */ + @ApiModelProperty(value = "抄送主键", required = true) + @NotNull(message = "抄送主键不能为空", groups = { EditGroup.class }) + private Long copyId; + + /** + * 抄送标题 + */ + @ApiModelProperty(value = "抄送标题", required = true) + @NotNull(message = "抄送标题不能为空", groups = { AddGroup.class, EditGroup.class }) + private String title; + + /** + * 流程主键 + */ + @ApiModelProperty(value = "流程主键", required = true) + @NotBlank(message = "流程主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private String processId; + + /** + * 流程名称 + */ + @ApiModelProperty(value = "流程名称", required = true) + @NotBlank(message = "流程名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String processName; + + /** + * 流程分类主键 + */ + @ApiModelProperty(value = "流程分类主键", required = true) + @NotBlank(message = "流程分类主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private String categoryId; + + /** + * 任务主键 + */ + @ApiModelProperty(value = "任务主键", required = true) + @NotBlank(message = "任务主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private String taskId; + + /** + * 用户主键 + */ + @ApiModelProperty(value = "用户主键", required = true) + @NotNull(message = "用户主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 发起人Id + */ + @ApiModelProperty(value = "发起人主键", required = true) + @NotNull(message = "发起人主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long originatorId; + /** + * 发起人名称 + */ + @ApiModelProperty(value = "发起人名称", required = true) + @NotNull(message = "发起人名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String originatorName; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java index 9ba8044d..3314d933 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java @@ -20,6 +20,9 @@ public class WfTaskBo { @ApiModelProperty("任务Id") private String taskId; + @ApiModelProperty("任务名称") + private String taskName; + @ApiModelProperty("用户Id") private String userId; @@ -43,4 +46,7 @@ public class WfTaskBo { @ApiModelProperty("审批组") private List candidateGroups; + + @ApiModelProperty("抄送用户Id") + private String copyUserIds; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfCopyVo.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfCopyVo.java new file mode 100644 index 00000000..cbb5d77e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/vo/WfCopyVo.java @@ -0,0 +1,108 @@ +package com.ruoyi.workflow.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + + +/** + * 流程抄送视图对象 wf_copy + * + * @author ruoyi + * @date 2022-05-19 + */ +@Data +@ApiModel("流程抄送视图对象") +@ExcelIgnoreUnannotated +public class WfCopyVo { + + private static final long serialVersionUID = 1L; + + /** + * 抄送主键 + */ + @ExcelProperty(value = "抄送主键") + @ApiModelProperty("抄送主键") + private Long copyId; + + /** + * 抄送标题 + */ + @ExcelProperty(value = "抄送标题") + @ApiModelProperty("抄送标题") + private String title; + + /** + * 流程主键 + */ + @ExcelProperty(value = "流程主键") + @ApiModelProperty("流程主键") + private String processId; + + /** + * 流程名称 + */ + @ExcelProperty(value = "流程名称") + @ApiModelProperty("流程名称") + private String processName; + + /** + * 流程分类主键 + */ + @ExcelProperty(value = "流程分类主键") + @ApiModelProperty("流程分类主键") + private String categoryId; + + /** + * 部署主键 + */ + @ExcelProperty(value = "部署主键") + @ApiModelProperty("部署主键") + private String deploymentId; + + /** + * 流程实例主键 + */ + @ExcelProperty(value = "流程实例主键") + @ApiModelProperty("流程实例主键") + private String instanceId; + + /** + * 任务主键 + */ + @ExcelProperty(value = "任务主键") + @ApiModelProperty("任务主键") + private String taskId; + + /** + * 用户主键 + */ + @ExcelProperty(value = "用户主键") + @ApiModelProperty("用户主键") + private Long userId; + + /** + * 发起人Id + */ + @ExcelProperty(value = "发起人主键") + @ApiModelProperty("发起人主键") + private Long originatorId; + + /** + * 发起人名称 + */ + @ExcelProperty(value = "发起人名称") + @ApiModelProperty("发起人名称") + private String originatorName; + + /** + * 抄送时间(创建时间) + */ + @ExcelProperty(value = "抄送时间") + @ApiModelProperty("抄送时间") + private Date createTime; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/mapper/WfCopyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/mapper/WfCopyMapper.java new file mode 100644 index 00000000..5724e6c3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/mapper/WfCopyMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.workflow.mapper; + +import com.ruoyi.common.core.mapper.BaseMapperPlus; +import com.ruoyi.workflow.domain.WfCopy; +import com.ruoyi.workflow.domain.vo.WfCopyVo; + +/** + * 流程抄送Mapper接口 + * + * @author KonBAI + * @date 2022-05-19 + */ +public interface WfCopyMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfCopyService.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfCopyService.java new file mode 100644 index 00000000..c789d378 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfCopyService.java @@ -0,0 +1,49 @@ +package com.ruoyi.workflow.service; + +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.workflow.domain.bo.WfCopyBo; +import com.ruoyi.workflow.domain.bo.WfTaskBo; +import com.ruoyi.workflow.domain.vo.WfCopyVo; + +import java.util.List; + +/** + * 流程抄送Service接口 + * + * @author KonBAI + * @date 2022-05-19 + */ +public interface IWfCopyService { + + /** + * 查询流程抄送 + * + * @param copyId 流程抄送主键 + * @return 流程抄送 + */ + WfCopyVo queryById(Long copyId); + + /** + * 查询流程抄送列表 + * + * @param wfCopy 流程抄送 + * @return 流程抄送集合 + */ + TableDataInfo queryPageList(WfCopyBo wfCopy, PageQuery pageQuery); + + /** + * 查询流程抄送列表 + * + * @param wfCopy 流程抄送 + * @return 流程抄送集合 + */ + List queryList(WfCopyBo wfCopy); + + /** + * 抄送 + * @param taskBo + * @return + */ + Boolean makeCopy(WfTaskBo taskBo); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfCopyServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfCopyServiceImpl.java new file mode 100644 index 00000000..ba72e0c9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfCopyServiceImpl.java @@ -0,0 +1,113 @@ +package com.ruoyi.workflow.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.workflow.domain.WfCopy; +import com.ruoyi.workflow.domain.bo.WfCopyBo; +import com.ruoyi.workflow.domain.bo.WfTaskBo; +import com.ruoyi.workflow.domain.vo.WfCopyVo; +import com.ruoyi.workflow.mapper.WfCopyMapper; +import com.ruoyi.workflow.service.IWfCopyService; +import lombok.RequiredArgsConstructor; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 流程抄送Service业务层处理 + * + * @author KonBAI + * @date 2022-05-19 + */ +@RequiredArgsConstructor +@Service +public class WfCopyServiceImpl implements IWfCopyService { + + private final WfCopyMapper baseMapper; + + private final RuntimeService runtimeService; + + /** + * 查询流程抄送 + * + * @param copyId 流程抄送主键 + * @return 流程抄送 + */ + @Override + public WfCopyVo queryById(Long copyId){ + return baseMapper.selectVoById(copyId); + } + + /** + * 查询流程抄送列表 + * + * @param bo 流程抄送 + * @return 流程抄送 + */ + @Override + public TableDataInfo queryPageList(WfCopyBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + lqw.orderByDesc(WfCopy::getCreateTime); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询流程抄送列表 + * + * @param bo 流程抄送 + * @return 流程抄送 + */ + @Override + public List queryList(WfCopyBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(WfCopyBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getProcessName()), WfCopy::getProcessName, bo.getProcessName()); + lqw.like(StringUtils.isNotBlank(bo.getOriginatorName()), WfCopy::getOriginatorName, bo.getOriginatorName()); + return lqw; + } + + @Override + public Boolean makeCopy(WfTaskBo taskBo) { + if (StringUtils.isBlank(taskBo.getCopyUserIds())) { + // 若抄送用户为空,则不需要处理,返回成功 + return true; + } + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() + .processInstanceId(taskBo.getInstanceId()).singleResult(); + String[] ids = taskBo.getCopyUserIds().split(","); + List copyList = new ArrayList<>(ids.length); + Long originatorId = LoginHelper.getUserId(); + String originatorName = LoginHelper.getNickName(); + String title = processInstance.getProcessDefinitionName() + "-" + taskBo.getTaskName(); + for (String id : ids) { + Long userId = Long.valueOf(id); + WfCopy copy = new WfCopy(); + copy.setTitle(title); + copy.setProcessId(processInstance.getProcessDefinitionId()); + copy.setProcessName(processInstance.getProcessDefinitionName()); + copy.setDeploymentId(processInstance.getDeploymentId()); + copy.setInstanceId(taskBo.getInstanceId()); + copy.setTaskId(taskBo.getTaskId()); + copy.setUserId(userId); + copy.setOriginatorId(originatorId); + copy.setOriginatorName(originatorName); + copyList.add(copy); + } + return baseMapper.insertBatch(copyList); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java index 019436d9..6571bd1d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java @@ -21,6 +21,7 @@ import com.ruoyi.system.service.ISysUserService; import com.ruoyi.workflow.domain.bo.WfTaskBo; import com.ruoyi.workflow.domain.dto.WfNextDto; import com.ruoyi.workflow.domain.vo.WfViewerVo; +import com.ruoyi.workflow.service.IWfCopyService; import com.ruoyi.workflow.service.IWfTaskService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -64,6 +65,8 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ private final ISysRoleService sysRoleService; + private final IWfCopyService copyService; + /** * 完成任务 * @@ -89,6 +92,12 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ taskService.complete(taskBo.getTaskId()); } } + // 设置任务节点名称 + taskBo.setTaskName(task.getName()); + // 处理抄送用户 + if (!copyService.makeCopy(taskBo)) { + throw new RuntimeException("抄送任务失败"); + } } /** @@ -215,7 +224,11 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ } catch (FlowableException e) { throw new RuntimeException("无法取消或开始活动"); } - + // 设置任务节点名称 + bo.setTaskName(task.getName()); + if (!copyService.makeCopy(bo)) { + throw new RuntimeException("抄送任务失败"); + } } /** @@ -298,6 +311,12 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ } catch (FlowableException e) { throw new RuntimeException("无法取消或开始活动"); } + // 设置任务节点名称 + bo.setTaskName(task.getName()); + // 处理抄送用户 + if (!copyService.makeCopy(bo)) { + throw new RuntimeException("抄送任务失败"); + } } @@ -405,6 +424,12 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ taskService.setOwner(bo.getTaskId(), LoginHelper.getUserId().toString()); // 执行委派 taskService.delegateTask(bo.getTaskId(), bo.getUserId()); + // 设置任务节点名称 + bo.setTaskName(task.getName()); + // 处理抄送用户 + if (!copyService.makeCopy(bo)) { + throw new RuntimeException("抄送任务失败"); + } } @@ -438,6 +463,12 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ taskService.setOwner(bo.getTaskId(), LoginHelper.getUserId().toString()); // 转办任务 taskService.setAssignee(bo.getTaskId(), bo.getUserId()); + // 设置任务节点名称 + bo.setTaskName(task.getName()); + // 处理抄送用户 + if (!copyService.makeCopy(bo)) { + throw new RuntimeException("抄送任务失败"); + } } /** diff --git a/ruoyi-system/src/main/resources/mapper/workflow/WfCopyMapper.xml b/ruoyi-system/src/main/resources/mapper/workflow/WfCopyMapper.xml new file mode 100644 index 00000000..833e2100 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/workflow/WfCopyMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-ui/src/api/workflow/process.js b/ruoyi-ui/src/api/workflow/process.js index 3ba65436..e8ba5801 100644 --- a/ruoyi-ui/src/api/workflow/process.js +++ b/ruoyi-ui/src/api/workflow/process.js @@ -46,6 +46,15 @@ export function listFinishedProcess(query) { }) } +// 查询流程抄送列表 +export function listCopyProcess(query) { + return request({ + url: '/workflow/process/copyList', + method: 'get', + params: query + }) +} + // 完成任务 export function complete(data) { return request({ diff --git a/ruoyi-ui/src/views/workflow/work/copy.vue b/ruoyi-ui/src/views/workflow/work/copy.vue new file mode 100644 index 00000000..ae42415a --- /dev/null +++ b/ruoyi-ui/src/views/workflow/work/copy.vue @@ -0,0 +1,208 @@ + + + diff --git a/ruoyi-ui/src/views/workflow/work/detail.vue b/ruoyi-ui/src/views/workflow/work/detail.vue index 9f29262b..e3dc434c 100644 --- a/ruoyi-ui/src/views/workflow/work/detail.vue +++ b/ruoyi-ui/src/views/workflow/work/detail.vue @@ -1,7 +1,8 @@