增加oa定义流程列表功能

This commit is contained in:
wanggeng 2022-03-23 11:43:14 +08:00
parent 457849095a
commit 1a0d37d048
12 changed files with 586 additions and 7 deletions

View File

@ -0,0 +1,28 @@
package ink.wgink.module.activiti.controller.api.oa;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.activiti.service.oa.IOaService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName: OaController
* @Description: Oa管理
* @Author: wanggeng
* @Date: 2022/3/23 09:54
* @Version: 1.0
*/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "oa管理")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/oa")
public class OaController extends DefaultBaseController {
@Autowired
private IOaService oaService;
}

View File

@ -0,0 +1,64 @@
package ink.wgink.module.activiti.controller.api.oa;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.activiti.pojo.dtos.oa.OaTaskDTO;
import ink.wgink.module.activiti.service.oa.IOaFormReportService;
import ink.wgink.pojo.result.SuccessResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @ClassName: OAFormReportController
* @Description: OA表单上报
* @Author: wanggeng
* @Date: 2022/3/22 21:55
* @Version: 1.0
*/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "oa表单上报")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/oa-form-report")
public class OaFormReportController extends DefaultBaseController {
@Autowired
private IOaFormReportService oaFormReportService;
@ApiOperation(value = "保存表单(发起流程)", notes = "保存表单(发起流程)接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "processDefinitionId", value = "流程定义ID", paramType = "path"),
@ApiImplicitParam(name = "formCode", value = "表单编码", paramType = "path"),
@ApiImplicitParam(name = "formVersion", value = "表单版本", paramType = "path")
})
@PostMapping("save/definition-id/{processDefinitionId}/code/{formCode}/version/{formVersion}")
public SuccessResult save(@PathVariable("processDefinitionId") String processDefinitionId,
@PathVariable("formCode") String formCode,
@PathVariable("formVersion") Integer formVersion,
@RequestBody Map<String, Object> params) {
checkParams(params);
oaFormReportService.save(processDefinitionId, formCode, formVersion, params);
return new SuccessResult();
}
@ApiOperation(value = "我的任务(待办)", notes = "我的任务(待办)接口")
@GetMapping("list-task-of-mine")
public List<OaTaskDTO> listTaskOfMine() {
return oaFormReportService.listTaskOfMine();
}
private void checkParams(Map<String, Object> body) {
if (body.isEmpty()) {
throw new ParamsException("提交内容不能为空");
}
for (Map.Entry<String, Object> kv : body.entrySet()) {
String key = kv.getKey();
}
}
}

View File

@ -1,5 +1,7 @@
package ink.wgink.module.activiti.pojo.dtos; package ink.wgink.module.activiti.pojo.dtos;
import io.swagger.annotations.ApiModel;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -10,6 +12,7 @@ import java.util.Map;
* @Date: 2021/12/7 10:47 PM * @Date: 2021/12/7 10:47 PM
* @Version: 1.0 * @Version: 1.0
*/ */
@ApiModel
public class ActivitiProcdefDTO { public class ActivitiProcdefDTO {
private String id; private String id;

View File

@ -0,0 +1,96 @@
package ink.wgink.module.activiti.pojo.dtos.oa;
import io.swagger.annotations.ApiModel;
/**
* @ClassName: OaProcessDTO
* @Description: oa流程
* @Author: wanggeng
* @Date: 2022/3/23 10:00
* @Version: 1.0
*/
@ApiModel
public class OaProcdefDTO {
private String id;
private String name;
private String description;
private String processDefinitionId;
private Integer version;
private String deploymentId;
private String formKey;
private String formCode;
private Integer formVersion;
public String getId() {
return id == null ? "" : id.trim();
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name == null ? "" : name.trim();
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description == null ? "" : description.trim();
}
public void setDescription(String description) {
this.description = description;
}
public String getProcessDefinitionId() {
return processDefinitionId == null ? "" : processDefinitionId.trim();
}
public void setProcessDefinitionId(String processDefinitionId) {
this.processDefinitionId = processDefinitionId;
}
public Integer getVersion() {
return version == null ? 0 : version;
}
public void setVersion(int version) {
this.version = version;
}
public String getDeploymentId() {
return deploymentId == null ? "" : deploymentId.trim();
}
public void setDeploymentId(String deploymentId) {
this.deploymentId = deploymentId;
}
public String getFormKey() {
return formKey == null ? "" : formKey.trim();
}
public void setFormKey(String formKey) {
this.formKey = formKey;
}
public String getFormCode() {
return formCode == null ? "" : formCode.trim();
}
public void setFormCode(String formCode) {
this.formCode = formCode;
}
public Integer getFormVersion() {
return formVersion == null ? 0 : formVersion;
}
public void setFormVersion(Integer formVersion) {
this.formVersion = formVersion;
}
}

View File

@ -0,0 +1,87 @@
package ink.wgink.module.activiti.pojo.dtos.oa;
import io.swagger.annotations.ApiModel;
/**
* @ClassName: OaTaskDTO
* @Description: oa任务
* @Author: wanggeng
* @Date: 2022/3/23 09:33
* @Version: 1.0
*/
@ApiModel
public class OaTaskDTO {
private String taskId;
private String taskName;
private String taskDescription;
private String formCode;
private Integer formVersion;
private String getFormKey;
private String reportUid;
private String owner;
public String getTaskId() {
return taskId == null ? "" : taskId.trim();
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getTaskName() {
return taskName == null ? "" : taskName.trim();
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public String getTaskDescription() {
return taskDescription == null ? "" : taskDescription.trim();
}
public void setTaskDescription(String taskDescription) {
this.taskDescription = taskDescription;
}
public String getFormCode() {
return formCode == null ? "" : formCode.trim();
}
public void setFormCode(String formCode) {
this.formCode = formCode;
}
public Integer getFormVersion() {
return formVersion == null ? 0 : formVersion;
}
public void setFormVersion(Integer formVersion) {
this.formVersion = formVersion;
}
public String getGetFormKey() {
return getFormKey == null ? "" : getFormKey.trim();
}
public void setGetFormKey(String getFormKey) {
this.getFormKey = getFormKey;
}
public String getReportUid() {
return reportUid == null ? "" : reportUid.trim();
}
public void setReportUid(String reportUid) {
this.reportUid = reportUid;
}
public String getOwner() {
return owner == null ? "" : owner.trim();
}
public void setOwner(String owner) {
this.owner = owner;
}
}

View File

@ -0,0 +1,38 @@
package ink.wgink.module.activiti.service.oa;
import ink.wgink.module.activiti.pojo.dtos.oa.OaTaskDTO;
import java.util.List;
import java.util.Map;
/**
* @ClassName: IOAFormReportService
* @Description: OA表单上报
* @Author: wanggeng
* @Date: 2022/3/22 22:05
* @Version: 1.0
*/
public interface IOaFormReportService {
String KEY_FORM_CODE = "formCode";
String KEY_FORM_VERSION = "formVersion";
String KEY_REPORT_UID = "reportUid";
/**
* 保存表单
*
* @param processDefinitionId 流程定义ID
* @param formCode 表单编码
* @param formVersion 表单版本
* @param params 表单参数
*/
void save(String processDefinitionId, String formCode, Integer formVersion, Map<String, Object> params);
/**
* 我的任务待办
*
* @return
*/
List<OaTaskDTO> listTaskOfMine();
}

View File

@ -0,0 +1,33 @@
package ink.wgink.module.activiti.service.oa;
import ink.wgink.module.activiti.pojo.dtos.oa.OaProcdefDTO;
import ink.wgink.pojo.result.SuccessResultList;
import java.util.List;
/**
* @ClassName: IOaService
* @Description: Oa管理
* @Author: wanggeng
* @Date: 2022/3/23 09:55
* @Version: 1.0
*/
public interface IOaService {
/**
* 流程定义列表
*
* @return
*/
List<OaProcdefDTO> listProcdef();
/**
* 流程定义分页列表
*
* @param page
* @param rows
* @return
*/
SuccessResultList<List<OaProcdefDTO>> listPageProcdef(int page, int rows);
}

View File

@ -0,0 +1,73 @@
package ink.wgink.module.activiti.service.oa.impl;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.activiti.pojo.dtos.oa.OaTaskDTO;
import ink.wgink.module.activiti.service.oa.IOaFormReportService;
import ink.wgink.module.form.service.report.IFormReportService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName: OaFormReportServiceImpl
* @Description: oa表单上报
* @Author: wanggeng
* @Date: 2022/3/22 22:05
* @Version: 1.0
*/
@Service
public class OaFormReportServiceImpl extends DefaultBaseService implements IOaFormReportService {
@Autowired
private IFormReportService formReportService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Override
public void save(String processDefinitionId, String formCode, Integer formVersion, Map<String, Object> params) {
String uid = formReportService.saveAndReturnId(formCode, formVersion, params);
LOG.debug("定义流程变量");
Map<String, Object> variables = getHashMap(4);
variables.put(KEY_FORM_CODE, formCode);
variables.put(KEY_FORM_VERSION, formVersion);
variables.put(KEY_REPORT_UID, uid);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
// 更新表单数据的流程实例ID
formReportService.updateProcessInstanceId(formCode, formVersion, uid, processInstance.getProcessInstanceId());
}
@Override
public List<OaTaskDTO> listTaskOfMine() {
String userId = securityComponent.getCurrentUser().getUserId();
TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
List<Task> tasks = taskQuery.list();
List<OaTaskDTO> oaTaskDTOs = new ArrayList<>();
tasks.forEach(task -> {
OaTaskDTO oaTaskDTO = new OaTaskDTO();
oaTaskDTO.setTaskId(task.getId());
oaTaskDTO.setTaskName(task.getName());
oaTaskDTO.setTaskDescription(task.getDescription());
oaTaskDTO.setOwner(task.getOwner());
Map<String, Object> variables = task.getProcessVariables();
oaTaskDTO.setFormCode(variables.get(KEY_FORM_CODE).toString());
oaTaskDTO.setFormVersion(Integer.parseInt(variables.get(KEY_FORM_VERSION).toString()));
oaTaskDTO.setReportUid(variables.get(KEY_REPORT_UID).toString());
oaTaskDTOs.add(oaTaskDTO);
});
return oaTaskDTOs;
}
}

View File

@ -0,0 +1,90 @@
package ink.wgink.module.activiti.service.oa.impl;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.activiti.pojo.dtos.oa.OaProcdefDTO;
import ink.wgink.module.activiti.service.oa.IOaService;
import ink.wgink.module.form.pojo.dtos.design.FormDTO;
import ink.wgink.module.form.service.design.IFormService;
import ink.wgink.pojo.result.SuccessResultList;
import org.activiti.engine.FormService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: OaServiceImpl
* @Description: oa管理
* @Author: wanggeng
* @Date: 2022/3/23 09:55
* @Version: 1.0
*/
@Service
public class OaServiceImpl extends DefaultBaseService implements IOaService {
@Autowired
private RepositoryService repositoryService;
@Autowired
private FormService formService;
@Autowired
private IFormService iFormService;
@Override
public List<OaProcdefDTO> listProcdef() {
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> processDefinitions = processDefinitionQuery.list();
return listOaProcdef(processDefinitions);
}
@Override
public SuccessResultList<List<OaProcdefDTO>> listPageProcdef(int page, int rows) {
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> processDefinitions = processDefinitionQuery.listPage(page - 1, rows);
List<OaProcdefDTO> oaProcdefDTOs = listOaProcdef(processDefinitions);
return new SuccessResultList<>(oaProcdefDTOs, page, processDefinitionQuery.count());
}
/**
* 流程定义列表
*
* @param processDefinitions
* @return
*/
private List<OaProcdefDTO> listOaProcdef(List<ProcessDefinition> processDefinitions) {
if (processDefinitions.isEmpty()) {
return new ArrayList<>();
}
List<String> formIds = new ArrayList<>();
List<OaProcdefDTO> oaProcdefDTOs = new ArrayList<>();
processDefinitions.forEach(processDefinition -> {
String formKey = formService.getStartFormData(processDefinition.getId()).getFormKey();
OaProcdefDTO oaProcdefDTO = new OaProcdefDTO();
oaProcdefDTO.setId(processDefinition.getId());
oaProcdefDTO.setDeploymentId(processDefinition.getDeploymentId());
oaProcdefDTO.setName(processDefinition.getName());
oaProcdefDTO.setFormKey(formKey);
oaProcdefDTOs.add(oaProcdefDTO);
if (StringUtils.isBlank(formKey)) {
return;
}
formIds.add(formKey);
});
List<FormDTO> formDTOs = iFormService.listByIds(formIds);
oaProcdefDTOs.forEach(oaProcdefDTO -> {
formDTOs.forEach(formDTO -> {
if (!StringUtils.equals(oaProcdefDTO.getFormKey(), formDTO.getFormId())) {
return;
}
oaProcdefDTO.setFormCode(formDTO.getFormCode());
oaProcdefDTO.setFormVersion(formDTO.getFormVersion());
});
});
return oaProcdefDTOs;
}
}

View File

@ -47,6 +47,73 @@ var KisBpmAssignmentPopupCtrl = ['$scope', function ($scope) {
$scope.assignment.candidateUsers = [{value: ''}]; $scope.assignment.candidateUsers = [{value: ''}];
} }
$scope.selectUserId = function() {
top.dialog.dialogData.selectedUserIds = $scope.assignment.assignee;
top.dialog.open({
url: top.restAjax.path('route/department/user/select-user', []),
title: '选择用户',
width: '500px',
height: '500px',
closeBtn: 0,
onClose: function() {
var selectedUsers = top.dialog.dialogData.selectedDepartmentUsers;
// 这里写处理逻辑
if(selectedUsers && selectedUsers.length > 0) {
if(selectedUsers.length > 1) {
top.dialog.msg('处理人只能选择一位');
return;
}
$scope.assignment.assignee = selectedUsers[0].userId;
} else {
$scope.assignment.assignee = '';
}
$scope.$apply();
}
})
}
$scope.selectCandidateUserId = function() {
var userIds = '';
var candidateUsers = $scope.assignment.candidateUsers;
if(candidateUsers && candidateUsers.length > 0) {
for(var i = 0, item; item = candidateUsers[i++];) {
if(item == '') {
continue;
}
if(userIds.length > 0) {
userIds += '_';
}
userIds += item.value;
}
}
top.dialog.dialogData.selectedUserIds = userIds;
top.dialog.open({
url: top.restAjax.path('route/department/user/select-user', []),
title: '选择用户',
width: '500px',
height: '500px',
closeBtn: 0,
onClose: function() {
var selectedUsers = top.dialog.dialogData.selectedDepartmentUsers;
// 这里写处理逻辑
if(selectedUsers && selectedUsers.length > 0) {
var candidateUserArray = [];
for(var i = 0, item; item = selectedUsers[i++];) {
candidateUserArray.push({
value: item.userId
})
}
$scope.assignment.candidateUsers = candidateUserArray;
} else {
$scope.assignment.candidateUsers = [{
value: ''
}];
}
$scope.$apply();
}
})
}
// Click handler for + button after enum value // Click handler for + button after enum value
var userValueIndex = 1; var userValueIndex = 1;
$scope.addCandidateUserValue = function (index) { $scope.addCandidateUserValue = function (index) {

View File

@ -3,14 +3,15 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="close()">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="close()">&times;</button>
<h2 translate>处理人</h2> <h2 translate>代理人管理</h2>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row row-no-gutter"> <div class="row row-no-gutter">
<div class="form-group"> <div class="form-group">
<label for="assigneeField">处理人</label> <label for="assigneeField">代理人</label>
<input type="text" id="assigneeField" class="form-control" ng-model="assignment.assignee" placeholder="{{'PROPERTY.ASSIGNMENT.ASSIGNEE_PLACEHOLDER' | translate}}" /> <input type="text" id="assigneeField" class="form-control" ng-model="assignment.assignee" placeholder="输入选择代理人,如果是变量,可直接输入变量,无需选择"/>
<button ng-click="selectUserId()" style="margin-top: 5px;">选择代理人</button>
</div> </div>
</div> </div>
@ -18,10 +19,9 @@
<div class="form-group"> <div class="form-group">
<label for="userField">候选人列表</label> <label for="userField">候选人列表</label>
<div ng-repeat="candidateUser in assignment.candidateUsers"> <div ng-repeat="candidateUser in assignment.candidateUsers">
<input id="userField" class="form-control" type="text" ng-model="candidateUser.value" /> <input id="userField" class="form-control" type="text" ng-model="candidateUser.value" placeholder="输入选择候选人,如果是变量,可直接输入变量,无需选择"/>
<i class="glyphicon glyphicon-minus clickable-property" ng-click="removeCandidateUserValue($index)"></i>
<i ng-if="$index == (assignment.candidateUsers.length - 1)" class="glyphicon glyphicon-plus clickable-property" ng-click="addCandidateUserValue($index)"></i>
</div> </div>
<button ng-click="selectCandidateUserId()" style="margin-top: 5px;">选择候选人</button>
</div> </div>
</div> </div>

View File

@ -166,7 +166,7 @@
{ {
"id": "usertaskassignment", "id": "usertaskassignment",
"type": "Complex", "type": "Complex",
"title": "理人", "title": "理人",
"value": "", "value": "",
"description": "Assignment definition for the user task", "description": "Assignment definition for the user task",
"popular": true "popular": true