diff --git a/ruoyi-ui/src/views/business/workflow/activiti/task/index.vue b/ruoyi-ui/src/views/business/workflow/activiti/task/index.vue index 4f819958..f401288a 100644 --- a/ruoyi-ui/src/views/business/workflow/activiti/task/index.vue +++ b/ruoyi-ui/src/views/business/workflow/activiti/task/index.vue @@ -17,7 +17,7 @@ type="text" icon="el-icon-edit" @click="examineAndApprove (scope.row)" - v-hasPermi="['workflow:leave:edit']" + v-hasPermi="['activiti:task:query']" >审批 @@ -34,7 +34,7 @@ - + - + - diff --git a/ruoyi-ui/src/views/business/workflow/workflow/leave/index.vue b/ruoyi-ui/src/views/business/workflow/workflow/leave/index.vue index dab4feaf..bc47ccbe 100644 --- a/ruoyi-ui/src/views/business/workflow/workflow/leave/index.vue +++ b/ruoyi-ui/src/views/business/workflow/workflow/leave/index.vue @@ -6,6 +6,7 @@ v-model="queryParams.title" placeholder="请输入标题" clearable + maxlength="10" size="small" @keyup.enter.native="handleQuery" /> @@ -353,6 +354,7 @@ export default { this.reset() getLeave(row.id).then(response => { this.form = response.data + this.form.betDateTime =[response.data.leaveStartTime,response.data.leaveEndTime] this.open = true this.title = '修改请假' }) diff --git a/ruoyi-ui/src/views/business/workflow/workflow/leave/leaveHistoryForm.vue b/ruoyi-ui/src/views/business/workflow/workflow/leave/leaveHistoryForm.vue index 5cefe7ed..b795fdbd 100644 --- a/ruoyi-ui/src/views/business/workflow/workflow/leave/leaveHistoryForm.vue +++ b/ruoyi-ui/src/views/business/workflow/workflow/leave/leaveHistoryForm.vue @@ -21,19 +21,27 @@ +
+ + + + + + + + + + + + + + + +
-
-

{{ historyData.taskNodeName }}

-

审批人:{{ historyData.createName }}

-

审批时间:{{ historyData.createdDate }}

- - - - - -
+ diff --git a/xjs-business/xjs-business-workflow/bpmn/请假.bpmn b/xjs-business/xjs-business-workflow/bpmn/请假.bpmn new file mode 100644 index 00000000..4364ce68 --- /dev/null +++ b/xjs-business/xjs-business-workflow/bpmn/请假.bpmn @@ -0,0 +1,128 @@ + + + + 请假流程演示 + + + + + + + + + Flow_0q3bbjl + + + + + + + + + Flow_0p85954 + Flow_0ji7qcv + + + Flow_0p85954 + Flow_0ji7qcv + Flow_0q3bbjl + + + + + ${FormProperty_3qipis2==0} + + + + + + + 1 + + + + ${FormProperty_23u95jb==0} + + + + + + 2 + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/controller/TaskController.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/controller/TaskController.java index 185c8b19..d4d72069 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/controller/TaskController.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/controller/TaskController.java @@ -13,6 +13,7 @@ import com.xjs.activiti.domain.dto.ActWorkflowFormDataDTO; import com.xjs.activiti.service.IActTaskService; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.*; import java.text.ParseException; @@ -36,13 +37,12 @@ public class TaskController extends BaseController { PageDomain pageDomain = TableSupport.buildPageRequest(); Page hashMaps = actTaskService.selectProcessDefinitionList(pageDomain); return getDataTable(hashMaps); - - } //渲染表单 @GetMapping(value = "/formDataShow/{taskID}") + @RequiresPermissions("activiti:task:query") public AjaxResult formDataShow(@PathVariable("taskID") String taskID) { return AjaxResult.success(actTaskService.formDataShow(taskID)); @@ -50,8 +50,16 @@ public class TaskController extends BaseController { //保存表单 @PostMapping(value = "/formDataSave/{taskID}") + @RequiresPermissions("activiti:task:save") public AjaxResult formDataSave(@PathVariable("taskID") String taskID, @RequestBody List formData) throws ParseException { + for (ActWorkflowFormDataDTO formDatum : formData) { + Assert.notNull(formDatum.getControlValue(),"参数不能为空"); + + if (formDatum.getControlValue().length() > 100) { + throw new IllegalArgumentException("长度超出 100 限制"); + } + } return toAjax(actTaskService.formDataSave(taskID, formData)); } diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/domain/dto/ActTaskDTO.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/domain/dto/ActTaskDTO.java index 4b4b3b77..d8cfc7e7 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/domain/dto/ActTaskDTO.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/domain/dto/ActTaskDTO.java @@ -18,6 +18,8 @@ public class ActTaskDTO extends BaseEntity { private String id; + private String processInstanceId; + private String name; private String status; @@ -28,11 +30,17 @@ public class ActTaskDTO extends BaseEntity { private String definitionKey; private String businessKey; + /** + * 上一个节点处理人 + */ + private String assignee; + public ActTaskDTO() { } public ActTaskDTO(Task task, ProcessInstance processInstance) { this.id = task.getId(); + this.processInstanceId = task.getProcessInstanceId(); this.name = task.getName(); this.status = task.getStatus().toString(); this.createdDate = task.getCreatedDate(); @@ -41,6 +49,22 @@ public class ActTaskDTO extends BaseEntity { this.businessKey = processInstance.getBusinessKey(); } + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getAssignee() { + return assignee; + } + + public void setAssignee(String assignee) { + this.assignee = assignee; + } + public String getId() { return id; } diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ActTaskServiceImpl.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ActTaskServiceImpl.java index 95677c59..6c0f5de3 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ActTaskServiceImpl.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ActTaskServiceImpl.java @@ -2,6 +2,7 @@ package com.xjs.activiti.service.impl; +import cn.hutool.core.collection.CollUtil; import com.github.pagehelper.Page; import com.ruoyi.common.core.web.page.PageDomain; import com.ruoyi.common.security.utils.SecurityUtils; @@ -12,14 +13,15 @@ import com.xjs.activiti.service.IActTaskService; import com.xjs.activiti.service.IActWorkflowFormDataService; import org.activiti.api.runtime.shared.query.Pageable; import org.activiti.api.task.model.Task; -import org.activiti.api.task.model.builders.TaskPayloadBuilder; import org.activiti.api.task.runtime.TaskRuntime; import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.FormProperty; import org.activiti.bpmn.model.UserTask; +import org.activiti.engine.HistoryService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; +import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.TaskQuery; import org.activiti.runtime.api.model.impl.APITaskConverter; @@ -28,7 +30,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.ParseException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; /** @@ -52,9 +57,10 @@ public class ActTaskServiceImpl implements IActTaskService { private RuntimeService runtimeService; @Autowired private IActWorkflowFormDataService actWorkflowFormDataService; - @Autowired private APITaskConverter taskConverter; + @Autowired + private HistoryService historyService; @Override @@ -72,7 +78,26 @@ public class ActTaskServiceImpl implements IActTaskService { if (totalItems != 0) { Set processInstanceIdIds = tasks.parallelStream().map(Task::getProcessInstanceId).collect(Collectors.toSet()); List processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list(); - List actTaskDTOS = tasks.stream().map(t -> new ActTaskDTO(t, processInstanceList.parallelStream().filter(pi -> t.getProcessInstanceId().equals(pi.getId())).findAny().get())).collect(Collectors.toList()); + + List actTaskDTOS = tasks.stream() + .map(t -> { + ActTaskDTO actTaskDTO = new ActTaskDTO(t, processInstanceList.parallelStream() + .filter(pi -> + t.getProcessInstanceId().equals(pi.getId())).findAny().get()); + + //根据开始时间获取历史任务中的办理人 + List instanceList = historyService.createHistoricTaskInstanceQuery() + .processInstanceId(actTaskDTO.getProcessInstanceId()) + .orderByHistoricTaskInstanceStartTime() + .asc() + .list(); + if (CollUtil.isNotEmpty(instanceList)) { + actTaskDTO.setAssignee(instanceList.get(0).getAssignee()); + } + + return actTaskDTO; + }) + .collect(Collectors.toList()); list.addAll(actTaskDTOS); } return list; @@ -117,7 +142,6 @@ public class ActTaskServiceImpl implements IActTaskService { ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); - boolean hasVariables = false;//没有任何参数 HashMap variables = new HashMap(); //前端传来的字符串,拆分成每个控件 List acwfds = new ArrayList<>(); @@ -127,19 +151,21 @@ public class ActTaskServiceImpl implements IActTaskService { //构建参数集合 if (!"f".equals(awf.getControlIsParam())) { variables.put(awf.getControlId(), awf.getControlValue()); - hasVariables = true; } }//for结束 if (task.getAssignee() == null) { - taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build()); - } - if (hasVariables) { - //带参数完成任务 - taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID).withVariables(variables).build()); - } else { - taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID).build()); + //taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build()); + + String username = SecurityUtils.getUsername(); + taskService.claim(task.getId(), username); + } + //带参数完成任务 + //taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID).withVariables(variables).build()); + + taskService.complete(task.getId(), variables, true); + //taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID).build()); //写入数据库 return actWorkflowFormDataService.insertActWorkflowFormDatas(acwfds); diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ProcessDefinitionServiceImpl.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ProcessDefinitionServiceImpl.java index d8cbbef6..8160fc11 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ProcessDefinitionServiceImpl.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/activiti/service/impl/ProcessDefinitionServiceImpl.java @@ -84,6 +84,7 @@ public class ProcessDefinitionServiceImpl implements IProcessDefinitionService { @Override public int deleteProcessDefinitionById(String id) { try { + //true级联删除 false有关联则抛异常 repositoryService.deleteDeployment(id, true); } catch (Exception e) { throw new ActivitiException("该流程已使用!无法删除!如需删除,请先删除相关任务!"); diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/controller/WorkflowLeaveController.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/controller/WorkflowLeaveController.java index 56222e66..d052d36e 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/controller/WorkflowLeaveController.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/controller/WorkflowLeaveController.java @@ -9,11 +9,15 @@ import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.common.security.utils.SecurityUtils; +import com.xjs.validation.group.AddGroup; +import com.xjs.validation.group.SelectGroup; +import com.xjs.validation.group.UpdateGroup; import com.xjs.workflow.leave.domain.WorkflowLeave; import com.xjs.workflow.leave.service.IWorkflowLeaveService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; @@ -38,7 +42,7 @@ public class WorkflowLeaveController extends BaseController { @GetMapping("/list") @RequiresPermissions("workflow:leave:list") @ApiOperation("查询请假列表") - public TableDataInfo list(WorkflowLeave workflowLeave) { + public TableDataInfo list(@Validated(SelectGroup.class) WorkflowLeave workflowLeave) { startPage(); workflowLeave.setCreateBy(SecurityUtils.getUsername()); List list = workflowLeaveService.selectWorkflowLeaveAndTaskNameList(workflowLeave); @@ -98,7 +102,7 @@ public class WorkflowLeaveController extends BaseController { @Log(title = "请假", businessType = BusinessType.INSERT) @PostMapping @ApiOperation("新增请假") - public AjaxResult add(@RequestBody WorkflowLeave workflowLeave) { + public AjaxResult add(@Validated(AddGroup.class)@RequestBody WorkflowLeave workflowLeave) { return toAjax(workflowLeaveService.insertWorkflowLeave(workflowLeave)); } @@ -109,7 +113,7 @@ public class WorkflowLeaveController extends BaseController { @ApiOperation("修改请假") @PutMapping @RequiresPermissions("workflow:leave:edit") - public AjaxResult edit(@RequestBody WorkflowLeave workflowLeave) { + public AjaxResult edit(@Validated(UpdateGroup.class)@RequestBody WorkflowLeave workflowLeave) { return toAjax(workflowLeaveService.insertWorkflowLeave(workflowLeave)); } diff --git a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/domain/WorkflowLeave.java b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/domain/WorkflowLeave.java index 2e056f04..37dcda90 100644 --- a/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/domain/WorkflowLeave.java +++ b/xjs-business/xjs-business-workflow/src/main/java/com/xjs/workflow/leave/domain/WorkflowLeave.java @@ -2,9 +2,14 @@ package com.xjs.workflow.leave.domain; import com.ruoyi.common.core.annotation.Excel; import com.ruoyi.common.core.web.domain.BaseEntity; +import com.xjs.validation.group.AddGroup; +import com.xjs.validation.group.SelectGroup; +import com.xjs.validation.group.UpdateGroup; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.util.Date; /** @@ -25,18 +30,24 @@ public class WorkflowLeave extends BaseEntity { * 请假类型 */ @Excel(name = "请假类型") + @NotBlank(message = "请假类型不能为空",groups = {AddGroup.class, UpdateGroup.class}) + @Size(min = 1, max = 5, message = "请假类型长度不能超过 10 个字符", groups = {SelectGroup.class, AddGroup.class, UpdateGroup.class}) private String type; /** * 标题 */ @Excel(name = "标题") + @NotBlank(message = "请假标题不能为空",groups = {AddGroup.class, UpdateGroup.class}) + @Size(min = 1, max = 100, message = "请假标题长度不能超过 10 个字符", groups = {SelectGroup.class, AddGroup.class, UpdateGroup.class}) private String title; /** * 原因 */ @Excel(name = "原因") + @NotBlank(message = "请假原因不能为空",groups = {AddGroup.class, UpdateGroup.class}) + @Size(min = 1, max = 500, message = "请假原因长度不能超过 500 个字符", groups = {AddGroup.class, UpdateGroup.class}) private String reason; /** @@ -58,7 +69,8 @@ public class WorkflowLeave extends BaseEntity { /** * 状态 */ - @Excel(name = "状态",readConverterExp = "0=进行中,1=成功,2=失败") + @Excel(name = "状态", readConverterExp = "0=进行中,1=成功,2=失败") + @Size(min = 1, max = 1, message = "请假状态长度不能超过 1 个字符", groups = {SelectGroup.class}) private String state; /**