nbcio-boot基于jeecg的flowable支持部门经理的单个或多实例支持(前端部分)

更多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做如下调整

javascript 复制代码
<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文件如下:

javascript 复制代码
<?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&gt;=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>
相关推荐
栈老师不回家3 分钟前
Vue 计算属性和监听器
前端·javascript·vue.js
前端啊龙9 分钟前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js
一颗松鼠13 分钟前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
小远yyds33 分钟前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
程序媛小果1 小时前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
小光学长1 小时前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端1 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱2 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai2 小时前
uniapp
前端·javascript·vue.js·uni-app