diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ProcessConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ProcessConstants.java index 1ba6548..b1e86a0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ProcessConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ProcessConstants.java @@ -2,26 +2,51 @@ package com.ruoyi.common.constant; /** * 流程常量信息 + * * @author Xuan xuan * @date 2021/4/17 22:46 */ public class ProcessConstants { - /** 动态数据 */ + /** + * 动态数据 + */ public static final String DATA_TYPE = "dynamic"; - - /** 单个审批人 */ + /** + * 单个审批人 + */ public static final String USER_TYPE_ASSIGNEE = "assignee"; - /** 候选人 */ + /** + * 候选人 + */ public static final String USER_TYPE_USERS = "candidateUsers"; - /** 审批组 */ + /** + * 审批组 + */ public static final String USER_TYPE_ROUPS = "candidateGroups"; - /** 单个审批人 */ + /** + * 单个审批人 + */ public static final String PROCESS_APPROVAL = "approval"; + + /** + * nameapace + */ + public static final String NAMASPASE = "http://flowable.org/bpmn"; + + /** + * 自定义属性 dataType + */ + public static final String PROCESS_CUSTOM_DATA_TYPE = "dataType"; + + /** + * 自定义属性 userType + */ + public static final String PROCESS_CUSTOM_USER_TYPE = "userType"; } diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java index 3f14e3c..8c5111c 100644 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java +++ b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/controller/FlowDefinitionController.java @@ -1,10 +1,12 @@ package com.ruoyi.flowable.controller; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.flowable.domain.dto.FlowProcDefDto; import com.ruoyi.flowable.domain.dto.FlowSaveXmlVo; import com.ruoyi.flowable.service.IFlowDefinitionService; +import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -14,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; @@ -45,6 +48,9 @@ public class FlowDefinitionController { @Autowired private ISysUserService userService; + @Resource + private ISysRoleService sysRoleService; + @GetMapping(value = "/list") @ApiOperation(value = "流程定义列表", response = FlowProcDefDto.class) @@ -173,4 +179,11 @@ public class FlowDefinitionController { return AjaxResult.success(list); } + @ApiOperation(value = "指定流程办理组列表") + @GetMapping("/roleList") + public AjaxResult roleList(SysRole role) { + List list = sysRoleService.selectRoleList(role); + return AjaxResult.success(list); + } + } \ No newline at end of file diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java index fc041b3..cb00be4 100644 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java +++ b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/dto/FlowNextDto.java @@ -1,5 +1,6 @@ package com.ruoyi.flowable.domain.dto; +import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import lombok.Data; @@ -19,4 +20,6 @@ public class FlowNextDto implements Serializable { private String vars; private List userList; + + private List roleList; } diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java index e3c89e7..b90aaea 100644 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java +++ b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java @@ -11,11 +11,14 @@ import com.ruoyi.system.domain.SysForm; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.flowable.bpmn.model.BpmnModel; +import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.repository.ProcessDefinitionQuery; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.image.impl.DefaultProcessDiagramGenerator; +import org.flowable.task.api.Task; +import org.flowable.task.api.TaskQuery; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -153,10 +156,12 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl try { // 设置流程发起人Id到流程中 Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); - identityService.setAuthenticatedUserId(userId.toString()); - variables.put("initiator",userId); +// identityService.setAuthenticatedUserId(userId.toString()); + Authentication.setAuthenticatedUserId(userId.toString()); + variables.put("skip", true); + variables.put("INITIATOR",userId.toString()); variables.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true); - runtimeService.startProcessInstanceById(procDefId, variables); + ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables); return AjaxResult.success("流程启动成功"); } catch (Exception e) { e.printStackTrace(); diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java index c38318a..f305873 100644 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java +++ b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java @@ -105,7 +105,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask // 设置任务审批人员 taskService.setAssignee(task.getTaskId(), userId.toString()); // 提交任务 - taskService.complete(task.getTaskId(),task.getValues()); + taskService.complete(task.getTaskId(), task.getValues()); } @@ -753,6 +753,9 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask // 第一次申请获取初始化表单 if (StringUtils.isNotBlank(deployId)) { SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId); + if (Objects.isNull(sysForm)){ + return AjaxResult.error("请先配置流程表单"); + } map.put("formData", JSONObject.parseObject(sysForm.getFormContent())); } return AjaxResult.success(map); @@ -861,25 +864,40 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask FlowElement targetFlow = sequenceFlow.getTargetFlowElement(); if (targetFlow instanceof UserTask) { - // 当流程设计时未指定任务接受人员/组时 判定为用户动态选择下一任务审批人 + // 读取自定义属性 动态选择下一任务审批人 // todo 1. 读取自定义节点属性来验证是否动态选择审批人 // 2. 验证表达式 - String dataType = targetFlow.getAttributeValue("http://flowable.org/bpmn", "dataType"); - String userType = targetFlow.getAttributeValue("http://flowable.org/bpmn", "userType"); -// Map> attributes = targetFlow.getAttributes(); -// List extensionAttributes = attributes.get("dataType"); -// for (ExtensionAttribute attribute : extensionAttributes) { -// String value = attribute.getValue(); -// } - if (ProcessConstants.DATA_TYPE.equals(dataType)){ - if (ProcessConstants.USER_TYPE_ASSIGNEE.equals(userType)){ + String dataType = targetFlow.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); + String userType = targetFlow.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE); + + + if (ProcessConstants.DATA_TYPE.equals(dataType)) { + // 指定单个人员 + if (ProcessConstants.USER_TYPE_ASSIGNEE.equals(userType)) { List list = sysUserService.selectUserList(new SysUser()); flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL); flowNextDto.setType(ProcessConstants.USER_TYPE_ASSIGNEE); flowNextDto.setUserList(list); } + // 候选人员(多个) + if (ProcessConstants.USER_TYPE_USERS.equals(userType)) { + List list = sysUserService.selectUserList(new SysUser()); + + flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL); + flowNextDto.setType(ProcessConstants.USER_TYPE_USERS); + flowNextDto.setUserList(list); + } + // 候选组 + if (ProcessConstants.USER_TYPE_ROUPS.equals(userType)) { + List sysRoles = sysRoleService.selectRoleAll(); + flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL); + flowNextDto.setType(ProcessConstants.USER_TYPE_ROUPS); + flowNextDto.setRoleList(sysRoles); + } } + } else if (targetFlow instanceof EndEvent) { + return AjaxResult.success("流程已完结", null); } } } diff --git a/ruoyi-ui/src/api/flowable/definition.js b/ruoyi-ui/src/api/flowable/definition.js index bfad61c..5c1411f 100644 --- a/ruoyi-ui/src/api/flowable/definition.js +++ b/ruoyi-ui/src/api/flowable/definition.js @@ -44,6 +44,15 @@ export function userList(query) { }) } +// 指定流程办理组列表 +export function roleList(query) { + return request({ + url: '/flowable/definition/roleList', + method: 'get', + params: query + }) +} + // 读取xml文件 export function readXml(deployId) { return request({ diff --git a/ruoyi-ui/src/components/Process/PropertyPanel.vue b/ruoyi-ui/src/components/Process/PropertyPanel.vue index 5744f26..970bd0f 100644 --- a/ruoyi-ui/src/components/Process/PropertyPanel.vue +++ b/ruoyi-ui/src/components/Process/PropertyPanel.vue @@ -9,6 +9,7 @@ :users="users" :groups="groups" :categorys="categorys" + @dataType="dataType" /> @@ -134,6 +135,10 @@ export default { }) } }) + }, + /** 获取数据类型 */ + dataType(data){ + this.$emit('dataType', data) } } } diff --git a/ruoyi-ui/src/components/Process/components/nodePanel/process.vue b/ruoyi-ui/src/components/Process/components/nodePanel/process.vue index 6498d48..6946f1e 100644 --- a/ruoyi-ui/src/components/Process/components/nodePanel/process.vue +++ b/ruoyi-ui/src/components/Process/components/nodePanel/process.vue @@ -53,7 +53,7 @@ export default { xType: 'select', name: 'processCategory', label: '流程分类', - dic: { data: _this.categorys, label: 'name', value: 'id' } + dic: { data: _this.categorys, label: 'dictLabel', value: 'dictValue' } }, { xType: 'input', diff --git a/ruoyi-ui/src/components/Process/components/nodePanel/startEnd.vue b/ruoyi-ui/src/components/Process/components/nodePanel/startEnd.vue index f16fe22..4c26dcd 100644 --- a/ruoyi-ui/src/components/Process/components/nodePanel/startEnd.vue +++ b/ruoyi-ui/src/components/Process/components/nodePanel/startEnd.vue @@ -72,7 +72,9 @@ export default { }, watch: { 'formData.initiator': function(val) { - if (val === '') val = null + // if (val === '') val = null + // 默认设置流程发起人 + if (val === '') val = 'INITIATOR' this.updateProperties({ 'flowable:initiator': val }) }, 'formData.formKey': function(val) { @@ -81,6 +83,7 @@ export default { } }, created() { + this.updateProperties({ 'flowable:initiator': 'INITIATOR' }) this.formData = commonParse(this.element) } } diff --git a/ruoyi-ui/src/components/Process/components/nodePanel/task.vue b/ruoyi-ui/src/components/Process/components/nodePanel/task.vue index 3c37b40..61a00d1 100644 --- a/ruoyi-ui/src/components/Process/components/nodePanel/task.vue +++ b/ruoyi-ui/src/components/Process/components/nodePanel/task.vue @@ -125,7 +125,8 @@ export default { name: 'dataType', label: '指定方式', dic: _this.dataTypeOption, - show: !!_this.showConfig.dataType + show: !!_this.showConfig.dataType, + rules: [{ required: true, message: '请指定方式' }] }, // { // xType: 'input', @@ -171,7 +172,7 @@ export default { multiple: true, allowCreate: true, filterable: true, - dic: { data: _this.groups, label: 'name', value: 'id' }, + dic: { data: _this.groups, label: 'roleName', value: 'roleId' }, show: !!_this.showConfig.candidateGroups && _this.formData.userType === 'candidateGroups' }, { @@ -287,9 +288,20 @@ export default { const that = this this.updateProperties({'flowable:dataType': val}) if (val === 'dynamic') { - debugger this.updateProperties({'flowable:userType': that.formData.userType}) } + // 切换时 删除之前选中的值 + const types = ['assignee', 'candidateUsers', 'candidateGroups'] + types.forEach(type => { + delete this.element.businessObject.$attrs[`flowable:${type}`] + delete this.formData[type] + }) + // 传值到父组件 + const params = { + dataType: val, + userType: this.formData.userType + } + this.$emit('dataType', params) }, 'formData.assignee': function(val) { if (this.formData.userType !== 'assignee') { diff --git a/ruoyi-ui/src/components/Process/index.vue b/ruoyi-ui/src/components/Process/index.vue index 211fd38..c61e28b 100644 --- a/ruoyi-ui/src/components/Process/index.vue +++ b/ruoyi-ui/src/components/Process/index.vue @@ -41,7 +41,7 @@
- + @@ -290,6 +290,7 @@ export default { async showXML() { try { const { xml } = await this.modeler.saveXML({ format: true }) + debugger this.$emit('showXML',xml) } catch (err) { console.log(err) @@ -329,6 +330,10 @@ export default { a.download = filename a.click() window.URL.revokeObjectURL(url) + }, + /** 获取数据类型 */ + dataType(data){ + this.$emit('dataType', data) } } } diff --git a/ruoyi-ui/src/views/flowable/definition/index.vue b/ruoyi-ui/src/views/flowable/definition/index.vue index a19c7bd..1b3747f 100644 --- a/ruoyi-ui/src/views/flowable/definition/index.vue +++ b/ruoyi-ui/src/views/flowable/definition/index.vue @@ -122,10 +122,17 @@ 配置表单 + + + + + + + { + // this.formList = res.rows; + // this.formDeployOpen = true; + // this.formDeployTitle = "挂载表单"; + // }) + // }, /** 挂载表单 */ submitFormDeploy(){ addDeployForm(this.formDeployParam).then(res =>{ diff --git a/ruoyi-ui/src/views/flowable/definition/model.vue b/ruoyi-ui/src/views/flowable/definition/model.vue index 18e1c75..2e33117 100644 --- a/ruoyi-ui/src/views/flowable/definition/model.vue +++ b/ruoyi-ui/src/views/flowable/definition/model.vue @@ -9,6 +9,7 @@ :is-view="false" @save="save" @showXML="showXML" + @dataType="dataType" /> @@ -23,11 +24,12 @@