更多ruoyi-nbcio功能请看演示系统
gitee源代码地址
前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio
演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/
更多nbcio-boot功能请看演示系统
gitee源代码地址
后端代码: https://gitee.com/nbacheng/nbcio-boot
前端代码:https://gitee.com/nbacheng/nbcio-vue.git
在线演示(包括H5) : http://218.75.87.38:9888
1、前端主要是UserTask.vue做如下调整
<template> <div style="margin-top: 16px"> <el-row> <h4><b>设置用户类型</b></h4> <el-radio-group v-model="defaultTaskForm.dataType" @change="changeDataType"> <div v-if="bDisplayUser"> <el-radio label="ASSIGNEE">指定用户</el-radio> <el-radio label="INITIATOR">发起人</el-radio> </div> <el-radio label="MANAGER">部门经理</el-radio> <el-radio label="USERS">候选用户</el-radio> <el-radio label="ROLES">候选角色</el-radio> </el-radio-group> </el-row> <el-row> <div v-if="defaultTaskForm.dataType === 'ASSIGNEE'"> <el-select v-model="userTaskForm.assignee" filterable allow-create clearable @change="updateElementTask('assignee')"> <el-option v-for="ak in users" :key="ak.id" :label="ak.name" :value="ak.id" /> </el-select> </div> </el-row> <el-row> <div v-if="defaultTaskForm.dataType === 'USERS'"> <el-select v-model="userTaskForm.candidateUsers" filterable allow-create multiple collapse-tags @change="updateElementTask('candidateUsers')"> <el-option v-for="uk in users" :key="uk.id" :label="uk.name" :value="uk.id" /> </el-select> </div> </el-row> <el-row> <div v-if="defaultTaskForm.dataType === 'ROLES'"> <el-select v-model="userTaskForm.candidateGroups" filterable allow-create multiple collapse-tags @change="updateElementTask('candidateGroups')"> <el-option v-for="gk in groups" :key="gk.id" :label="gk.name" :value="gk.id" /> </el-select> </div> </el-row> <el-row v-if="defaultTaskForm.dataType === 'USERS' || defaultTaskForm.dataType === 'ROLES' || defaultTaskForm.dataType === 'MANAGER'"> <h4><b>多实例</b></h4> <div> <element-multi-instance :business-object="bpmnElement.businessObject" @multiInsEvent="multiIns"/> </div> </el-row> <!-- <el-form-item label="到期时间"> <el-input v-model="userTaskForm.dueDate" clearable @change="updateElementTask('dueDate')" /> </el-form-item> <el-form-item label="跟踪时间"> <el-input v-model="userTaskForm.followUpDate" clearable @change="updateElementTask('followUpDate')" /> </el-form-item> <el-form-item label="优先级"> <el-input v-model="userTaskForm.priority" clearable @change="updateElementTask('priority')" /> </el-form-item> --> </div> </template> <script> import ElementMultiInstance from "../../multi-instance/ElementMultiInstance"; export default { name: "UserTask", components: { ElementMultiInstance, }, props: { users: {//兼容老系统add by nbacheng type: Array, required: true }, groups: {//兼容老系统 type: Array, required: true }, id: String, type: String }, data() { return { defaultTaskForm: { assignee: "", candidateUsers: [], candidateGroups: [], dueDate: "", followUpDate: "", priority: "", dataType: "", }, userTaskForm: {}, bDisplayUser: true, }; }, watch: { id: { immediate: true, handler() { this.bpmnElement = window.bpmnInstances.bpmnElement; console.log("watch this.bpmnElement",this.bpmnElement) if (this.containsKey(this.bpmnElement.businessObject, 'loopCharacteristics') && this.bpmnElement.businessObject.loopCharacteristics != null) { this.bDisplayUser = false; if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') && this.bpmnElement.businessObject.candidateUsers != null) { this.defaultTaskForm.dataType = "USERS"; } if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') && this.bpmnElement.businessObject.candidateGroups != null) { this.defaultTaskForm.dataType = "ROLES"; } if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') && this.bpmnElement.businessObject.candidateGroups === '${DepManagerHandler.getUsers(execution)}') { this.defaultTaskForm.dataType = "MANAGER"; } } else { this.bDisplayUser = true; if (this.containsKey(this.bpmnElement.businessObject, 'assignee') && this.bpmnElement.businessObject.assignee != null) { this.defaultTaskForm.dataType = "ASSIGNEE"; } if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') && this.bpmnElement.businessObject.candidateUsers != null) { this.defaultTaskForm.dataType = "USERS"; } if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') && this.bpmnElement.businessObject.candidateGroups != null) { this.defaultTaskForm.dataType = "ROLES"; } if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') && this.bpmnElement.businessObject.candidateGroups === '${DepManagerHandler.getUsers(execution)}') { this.defaultTaskForm.dataType = "MANAGER"; } if (this.containsKey(this.bpmnElement.businessObject, 'assignee') && this.bpmnElement.businessObject.assignee === '${INITIATOR}') { this.defaultTaskForm.dataType = "INITIATOR"; } } this.$nextTick(() => this.resetTaskForm()); } } }, methods: { multiIns(val) { //子组件传递是否是多实例 this.bDisplayUser = val; }, containsKey(obj, key ) { return Object.keys(obj).includes(key); }, resetTaskForm() { for (let key in this.defaultTaskForm) { let value; if (key === "candidateUsers" || key === "candidateGroups") { value = this.bpmnElement?.businessObject[key] ? this.bpmnElement.businessObject[key].split(",") : []; } else { value = this.bpmnElement?.businessObject[key] || this.defaultTaskForm[key]; } this.$set(this.userTaskForm, key, value); } }, changeDataType(val) { // 清空 userTaskForm 所有属性值 //Object.keys(this.userTaskForm).forEach(key => this.userTaskForm[key] = null); this.userTaskForm.dataType = val; if (val === 'INITIATOR') { this.userTaskForm.assignee = "${INITIATOR}"; this.userTaskForm.text = "流程发起人"; const taskAttr = Object.create(null); taskAttr['candidateUsers'] = null; taskAttr['candidateGroups'] = null; this.userTaskForm['candidateUsers'] = null; this.userTaskForm['candidateGroups'] = null; taskAttr['assignee'] = this.userTaskForm['assignee'] || null; window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr); } if (val === 'MANAGER') { this.userTaskForm.candidateGroups = "${DepManagerHandler.getUsers(execution)}"; this.userTaskForm.assignee="${assignee}" this.userTaskForm.text = "部门经理"; const taskAttr = Object.create(null); taskAttr['candidateUsers'] = null;ull; this.userTaskForm['candidateUsers'] = null; taskAttr['candidateGroups'] = this.userTaskForm['candidateGroups'] || null; taskAttr['assignee'] = this.userTaskForm['assignee'] || null; window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr); } }, updateElementTask(key) { const taskAttr = Object.create(null); if (key === "candidateUsers") { taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key].join() : null; if(taskAttr[key] !=null) { taskAttr['candidateGroups'] = null; taskAttr['assignee'] = null; this.userTaskForm['candidateGroups'] = null; this.userTaskForm['assignee'] = null; } } else if (key === "candidateGroups") { taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key].join() : null; if(taskAttr[key] !=null) { taskAttr['candidateUsers'] = null; taskAttr['assignee'] = null; this.userTaskForm['candidateUsers'] = null; this.userTaskForm['assignee'] = null; } } else if (key === "assignee") { taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key] : null; if(taskAttr[key] !=null) { taskAttr['candidateUsers'] = null; taskAttr['candidateGroups'] = null; this.userTaskForm['candidateUsers'] = null; this.userTaskForm['candidateGroups'] = null; } } else { taskAttr[key] = this.userTaskForm[key] || null; } window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr); } }, beforeDestroy() { this.bpmnElement = null; } }; </script>
2、例子如下:
3、xm文件如下:
<?xml version="1.0" encoding="UTF-8"?> <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" id="diagram_Flow_1714391339805" targetNamespace="http://bpmn.io/schema/bpmn"> <bpmn2:process id="Flow_1714391339805" name="流程_测试部门经理2" isExecutable="true" flowable:processCategory="oa"> <bpmn2:startEvent id="Event_0lgj24k" flowable:formKey="1567709993582768129"> <bpmn2:extensionElements> <flowable:formData /> </bpmn2:extensionElements> <bpmn2:outgoing>Flow_0zs3lof</bpmn2:outgoing> </bpmn2:startEvent> <bpmn2:userTask id="Activity_1089rl1" name="发起人" flowable:assignee="${INITIATOR}"> <bpmn2:extensionElements /> <bpmn2:incoming>Flow_0zs3lof</bpmn2:incoming> <bpmn2:outgoing>Flow_1v1hkd2</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="Flow_0zs3lof" sourceRef="Event_0lgj24k" targetRef="Activity_1089rl1" /> <bpmn2:userTask id="Activity_0b0kg4c" name="部门经理" flowable:assignee="${assignee}" flowable:candidateGroups="${DepManagerHandler.getUsers(execution)}"> <bpmn2:extensionElements> <flowable:formData /> </bpmn2:extensionElements> <bpmn2:incoming>Flow_1x9dbi0</bpmn2:incoming> <bpmn2:outgoing>Flow_1nybok9</bpmn2:outgoing> <bpmn2:multiInstanceLoopCharacteristics flowable:collection="${multiInstanceHandler.getUserName(execution)}" flowable:elementVariable="assignee"> <bpmn2:completionCondition xsi:type="bpmn2:tFormalExpression">${nrOfCompletedInstances>=nrOfInstances}</bpmn2:completionCondition> </bpmn2:multiInstanceLoopCharacteristics> </bpmn2:userTask> <bpmn2:userTask id="Activity_0hcvugc" name="发起人" flowable:assignee="${INITIATOR}"> <bpmn2:extensionElements> <flowable:formData /> </bpmn2:extensionElements> <bpmn2:incoming>Flow_1nybok9</bpmn2:incoming> <bpmn2:outgoing>Flow_0v3lbj9</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="Flow_1nybok9" sourceRef="Activity_0b0kg4c" targetRef="Activity_0hcvugc" /> <bpmn2:endEvent id="Event_1jxpzpp"> <bpmn2:incoming>Flow_0v3lbj9</bpmn2:incoming> </bpmn2:endEvent> <bpmn2:sequenceFlow id="Flow_0v3lbj9" sourceRef="Activity_0hcvugc" targetRef="Event_1jxpzpp" /> <bpmn2:userTask id="Activity_00gi95o" name="部门经理" flowable:assignee="${assignee}" flowable:candidateGroups="${DepManagerHandler.getUsers(execution)}"> <bpmn2:extensionElements> <flowable:formData /> </bpmn2:extensionElements> <bpmn2:incoming>Flow_1v1hkd2</bpmn2:incoming> <bpmn2:outgoing>Flow_1x9dbi0</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="Flow_1v1hkd2" sourceRef="Activity_1089rl1" targetRef="Activity_00gi95o" /> <bpmn2:sequenceFlow id="Flow_1x9dbi0" sourceRef="Activity_00gi95o" targetRef="Activity_0b0kg4c" /> </bpmn2:process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Flow_1714391339805"> <bpmndi:BPMNEdge id="Flow_1x9dbi0_di" bpmnElement="Flow_1x9dbi0"> <di:waypoint x="480" y="180" /> <di:waypoint x="550" y="180" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_1v1hkd2_di" bpmnElement="Flow_1v1hkd2"> <di:waypoint x="340" y="180" /> <di:waypoint x="380" y="180" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0v3lbj9_di" bpmnElement="Flow_0v3lbj9"> <di:waypoint x="810" y="180" /> <di:waypoint x="852" y="180" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_1nybok9_di" bpmnElement="Flow_1nybok9"> <di:waypoint x="650" y="180" /> <di:waypoint x="710" y="180" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0zs3lof_di" bpmnElement="Flow_0zs3lof"> <di:waypoint x="178" y="180" /> <di:waypoint x="240" y="180" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="Event_0lgj24k_di" bpmnElement="Event_0lgj24k"> <dc:Bounds x="142" y="162" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_1089rl1_di" bpmnElement="Activity_1089rl1"> <dc:Bounds x="240" y="140" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_0b0kg4c_di" bpmnElement="Activity_0b0kg4c"> <dc:Bounds x="550" y="140" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_0hcvugc_di" bpmnElement="Activity_0hcvugc"> <dc:Bounds x="710" y="140" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Event_1jxpzpp_di" bpmnElement="Event_1jxpzpp"> <dc:Bounds x="852" y="162" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_00gi95o_di" bpmnElement="Activity_00gi95o"> <dc:Bounds x="380" y="140" width="100" height="80" /> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </bpmn2:definitions>