ruoyi-nbcio-plus基于vue3的flowable执行监听器的升级修改

news2024/11/29 0:32:10

更多ruoyi-nbcio功能请看演示系统

gitee源代码地址

前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio

演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/

更多nbcio-boot功能请看演示系统 

gitee源代码地址

后端代码: https://gitee.com/nbacheng/nbcio-boot

前端代码:https://gitee.com/nbacheng/nbcio-vue.git

在线演示(包括H5) : http://122.227.135.243:9888

1、执行监听器的vue2代码如下:

<template>
  <div class="panel-tab__content">
    <el-table :data="elementListenersList" size="small" border>
      <el-table-column label="序号" width="50px" type="index" />
      <el-table-column label="事件类型" min-width="100px" prop="event" />
      <el-table-column label="监听器类型" min-width="100px" show-overflow-tooltip :formatter="row => listenerTypeObject[row.listenerType]" />
      <el-table-column label="操作" width="90px">
        <template v-slot="{ row, $index }">
          <el-button link type="" @click="openListenerForm(row, $index)">编辑</el-button>
          <el-divider direction="vertical" />
          <el-button link type="" style="color: #ff4d4f" @click="removeListener(row, $index)">移除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="element-drawer__button">
      <el-button size="small" type="primary" :icon="Plus" @click="openListenerForm(null)">添加监听器</el-button>
    </div>

    <!-- 监听器 编辑/创建 部分 -->
    <el-drawer v-model="listenerFormModelVisible" title="执行监听器" :size="`${width}px`" append-to-body destroy-on-close>
      <el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef" @submit.prevent>
        <el-form-item label="事件类型" prop="event" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerForm.event">
            <el-option label="start" value="start" />
            <el-option label="end" value="end" />
          </el-select>
        </el-form-item>
        <el-form-item label="监听器类型" prop="listenerType" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerForm.listenerType">
            <el-option v-for="i in Object.keys(listenerTypeObject)" :key="i" :label="listenerTypeObject[i]" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'classListener'"
          label="Java类"
          prop="class"
          key="listener-class"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.class" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'expressionListener'"
          label="表达式"
          prop="expression"
          key="listener-expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.expression" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'delegateExpressionListener'"
          label="代理表达式"
          prop="delegateExpression"
          key="listener-delegate"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.delegateExpression" clearable />
        </el-form-item>
        <template v-if="listenerForm.listenerType === 'scriptListener'">
          <el-form-item
            label="脚本格式"
            prop="scriptFormat"
            key="listener-script-format"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }"
          >
            <el-input v-model="listenerForm.scriptFormat" clearable />
          </el-form-item>
          <el-form-item
            label="脚本类型"
            prop="scriptType"
            key="listener-script-type"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }"
          >
            <el-select v-model="listenerForm.scriptType">
              <el-option label="内联脚本" value="inlineScript" />
              <el-option label="外部脚本" value="externalScript" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'inlineScript'"
            label="脚本内容"
            prop="value"
            key="listener-script"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }"
          >
            <el-input v-model="listenerForm.value" clearable />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'externalScript'"
            label="资源地址"
            prop="resource"
            key="listener-resource"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }"
          >
            <el-input v-model="listenerForm.resource" clearable />
          </el-form-item>
        </template>
      </el-form>
      <el-divider />
      <p class="listener-filed__title">
        <span><el-icon><Menu /></el-icon>注入字段:</span>
        <el-button size="small" type="primary" @click="openListenerFieldForm(null)">添加字段</el-button>
      </p>
      <el-table :data="fieldsListOfListener" size="small" max-height="240" border fit style="flex: none">
        <el-table-column label="序号" width="50px" type="index" />
        <el-table-column label="字段名称" min-width="100px" prop="name" />
        <el-table-column label="字段类型" min-width="80px" show-overflow-tooltip :formatter="row => fieldTypeObject[row.fieldType]" />
        <el-table-column label="字段值/表达式" min-width="100px" show-overflow-tooltip :formatter="row => row.string || row.expression" />
        <el-table-column label="操作" width="100px">
          <template v-slot="{ row, $index }">
            <el-button link type="" @click="openListenerFieldForm(row, $index)">编辑</el-button>
            <el-divider direction="vertical" />
            <el-button link type="" style="color: #ff4d4f" @click="removeListenerField(row, $index)">移除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="element-drawer__button">
        <el-button size="small" @click="listenerFormModelVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="saveListenerConfig">保 存</el-button>
      </div>
    </el-drawer>

    <!-- 注入西段 编辑/创建 部分 -->
    <el-dialog title="字段配置" v-model="listenerFieldFormModelVisible" width="600px" append-to-body destroy-on-close>
      <el-form :model="listenerFieldForm" size="small" label-width="96px" ref="listenerFieldFormRef" style="height: 136px" @submit.prevent>
        <el-form-item label="字段名称:" prop="name" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.name" clearable />
        </el-form-item>
        <el-form-item label="字段类型:" prop="fieldType" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerFieldForm.fieldType">
            <el-option v-for="i in Object.keys(fieldTypeObject)" :key="i" :label="fieldTypeObject[i]" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'string'"
          label="字段值:"
          prop="string"
          key="field-string"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.string" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'expression'"
          label="表达式:"
          prop="expression"
          key="field-expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.expression" clearable />
        </el-form-item>
      </el-form>
      <template v-slot:footer>
        <el-button size="small" @click="listenerFieldFormModelVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="saveListenerFiled">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { createListenerObject, updateElementExtensions } from "../../utils";
import { initListenerType, initListenerForm, listenerType, fieldType } from "./utilSelf";
import { Plus } from '@element-plus/icons-vue'

export default {
  name: "ElementListeners",
  setup() {
    return { Plus }
  },
  props: {
    id: String,
    type: String
  },
  inject: {
    prefix: "prefix",
    width: "width"
  },
  data() {
    return {
      elementListenersList: [], // 监听器列表
      listenerForm: {}, // 监听器详情表单
      listenerFormModelVisible: false, // 监听器 编辑 侧边栏显示状态
      fieldsListOfListener: [],
      listenerFieldForm: {}, // 监听器 注入字段 详情表单
      listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
      editingListenerIndex: -1, // 监听器所在下标,-1 为新增
      editingListenerFieldIndex: -1, // 字段所在下标,-1 为新增
      listenerTypeObject: listenerType,
      fieldTypeObject: fieldType
    };
  },
  watch: {
    id: {
      immediate: true,
      handler(val) {
        val && val.length && this.$nextTick(() => this.resetListenersList());
      }
    }
  },
  methods: {
    resetListenersList() {
      this.bpmnElement = window.bpmnInstances.bpmnElement;
      this.otherExtensionList = [];
      this.bpmnElementListeners =
        this.bpmnElement.businessObject?.extensionElements?.values?.filter(ex => ex.$type === `${this.prefix}:ExecutionListener`) ?? [];
      this.elementListenersList = this.bpmnElementListeners.map(listener => initListenerType(listener));
    },
    // 打开 监听器详情 侧边栏
    openListenerForm(listener, index) {
      if (listener) {
        this.listenerForm = initListenerForm(listener);
        this.editingListenerIndex = index;
      } else {
        this.listenerForm = {};
        this.editingListenerIndex = -1; // 标记为新增
      }
      if (listener && listener.fields) {
        this.fieldsListOfListener = listener.fields.map(field => ({
          ...field,
          fieldType: field.string ? "string" : "expression"
        }));
      } else {
        this.fieldsListOfListener = [];
        this.listenerForm["fields"] = []
      }
      // 打开侧边栏并清楚验证状态
      this.listenerFormModelVisible = true;
      this.$nextTick(() => {
        if (this.$refs["listenerFormRef"]) this.$refs["listenerFormRef"].clearValidate();
      });
    },
    // 打开监听器字段编辑弹窗
    openListenerFieldForm(field, index) {
      this.listenerFieldForm = field ? JSON.parse(JSON.stringify(field)) : {};
      this.editingListenerFieldIndex = field ? index : -1;
      this.listenerFieldFormModelVisible = true;
      this.$nextTick(() => {
        if (this.$refs["listenerFieldFormRef"]) this.$refs["listenerFieldFormRef"].clearValidate();
      });
    },
    // 保存监听器注入字段
    async saveListenerFiled() {
      let validateStatus = await this.$refs["listenerFieldFormRef"].validate();
      if (!validateStatus) return; // 验证不通过直接返回
      if (this.editingListenerFieldIndex === -1) {
        this.fieldsListOfListener.push(this.listenerFieldForm);
        this.listenerForm.fields.push(this.listenerFieldForm);
      } else {
        this.fieldsListOfListener.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm);
        this.listenerForm.fields.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm);
      }
      this.listenerFieldFormModelVisible = false;
      this.$nextTick(() => (this.listenerFieldForm = {}));
    },
    // 移除监听器字段
    removeListenerField(field, index) {
      this.$confirm("确认移除该字段吗?", "提示", {
        confirmButtonText: "确 认",
        cancelButtonText: "取 消"
      })
        .then(() => {
          this.fieldsListOfListener.splice(index, 1);
          this.listenerForm.fields.splice(index, 1);
        })
        .catch(() => console.info("操作取消"));
    },
    // 移除监听器
    removeListener(listener, index) {
      this.$confirm("确认移除该监听器吗?", "提示", {
        confirmButtonText: "确 认",
        cancelButtonText: "取 消"
      })
        .then(() => {
          this.bpmnElementListeners.splice(index, 1);
          this.elementListenersList.splice(index, 1);
          updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners));
        })
        .catch(() => console.info("操作取消"));
    },
    // 保存监听器配置
    async saveListenerConfig() {
      let validateStatus = await this.$refs["listenerFormRef"].validate();
      if (!validateStatus) return; // 验证不通过直接返回
      const listenerObject = createListenerObject(this.listenerForm, false, this.prefix);
      if (this.editingListenerIndex === -1) {
        this.bpmnElementListeners.push(listenerObject);
        this.elementListenersList.push(this.listenerForm);
      } else {
        this.bpmnElementListeners.splice(this.editingListenerIndex, 1, listenerObject);
        this.elementListenersList.splice(this.editingListenerIndex, 1, this.listenerForm);
      }
      // 保存其他配置
      this.otherExtensionList = this.bpmnElement.businessObject?.extensionElements?.values?.filter(ex => ex.$type !== `${this.prefix}:ExecutionListener`) ?? [];
      updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners));
      // 4. 隐藏侧边栏
      this.listenerFormModelVisible = false;
      this.listenerForm = {};
    }
  }
};
</script>

2、修改后的vue3代码如下:

<template>
  <div class="panel-tab__content">
    <el-table :data="elementListenersList" size="small" border>
      <el-table-column label="序号" width="50px" type="index" />
      <el-table-column label="事件类型" min-width="100px" prop="event" />
      <el-table-column label="监听器类型" min-width="100px" show-overflow-tooltip :formatter="row => listenerTypeObject[row.listenerType]" />
      <el-table-column label="操作" width="90px">
        <template #default="scope">
          <el-button link type="" @click="openListenerForm(scope.row, scope.$index)">编辑</el-button>
          <el-divider direction="vertical" />
          <el-button link type="" style="color: #ff4d4f" @click="removeListener(scope.row, scope.$index)">移除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="element-drawer__button">
      <el-button size="small" type="primary" :icon="Plus" @click="openListenerForm(null)">添加监听器</el-button>
    </div>

    <!-- 监听器 编辑/创建 部分 -->
    <el-drawer v-model="listenerFormModelVisible" title="执行监听器" :size="`${width}px`" append-to-body destroy-on-close>
      <el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef" @submit.prevent>
        <el-form-item label="事件类型" prop="event" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerForm.event">
            <el-option label="start" value="start" />
            <el-option label="end" value="end" />
          </el-select>
        </el-form-item>
        <el-form-item label="监听器类型" prop="listenerType" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerForm.listenerType">
            <el-option v-for="i in Object.keys(listenerTypeObject)" :key="i" :label="listenerTypeObject[i]" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'classListener'"
          label="Java类"
          prop="class"
          key="listener-class"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.class" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'expressionListener'"
          label="表达式"
          prop="expression"
          key="listener-expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.expression" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'delegateExpressionListener'"
          label="代理表达式"
          prop="delegateExpression"
          key="listener-delegate"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.delegateExpression" clearable />
        </el-form-item>
        <template v-if="listenerForm.listenerType === 'scriptListener'">
          <el-form-item
            label="脚本格式"
            prop="scriptFormat"
            key="listener-script-format"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }"
          >
            <el-input v-model="listenerForm.scriptFormat" clearable />
          </el-form-item>
          <el-form-item
            label="脚本类型"
            prop="scriptType"
            key="listener-script-type"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }"
          >
            <el-select v-model="listenerForm.scriptType">
              <el-option label="内联脚本" value="inlineScript" />
              <el-option label="外部脚本" value="externalScript" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'inlineScript'"
            label="脚本内容"
            prop="value"
            key="listener-script"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }"
          >
            <el-input v-model="listenerForm.value" clearable />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'externalScript'"
            label="资源地址"
            prop="resource"
            key="listener-resource"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }"
          >
            <el-input v-model="listenerForm.resource" clearable />
          </el-form-item>
        </template>
      </el-form>
      <el-divider />
      <p class="listener-filed__title">
        <span><el-icon><Menu /></el-icon>注入字段:</span>
        <el-button size="small" type="primary" @click="openListenerFieldForm(null)">添加字段</el-button>
      </p>
      <el-table :data="fieldsListOfListener" size="small" max-height="240" border fit style="flex: none">
        <el-table-column label="序号" width="50px" type="index" />
        <el-table-column label="字段名称" min-width="100px" prop="name" />
        <el-table-column label="字段类型" min-width="80px" show-overflow-tooltip :formatter="row => fieldTypeObject[row.fieldType]" />
        <el-table-column label="字段值/表达式" min-width="100px" show-overflow-tooltip :formatter="row => row.string || row.expression" />
        <el-table-column label="操作" width="100px">
          <template #default="scope">
            <el-button link type="" @click="openListenerFieldForm(scope.row, scope.$index)">编辑</el-button>
            <el-divider direction="vertical" />
            <el-button link type="" style="color: #ff4d4f" @click="removeListenerField(scope.row, scope.$index)">移除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="element-drawer__button">
        <el-button size="small" @click="listenerFormModelVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="saveListenerConfig">保 存</el-button>
      </div>
    </el-drawer>

    <!-- 注入西段 编辑/创建 部分 -->
    <el-dialog title="字段配置" v-model="listenerFieldFormModelVisible" width="600px" append-to-body destroy-on-close>
      <el-form :model="listenerFieldForm" size="small" label-width="96px" ref="listenerFieldFormRef" style="height: 136px" @submit.prevent>
        <el-form-item label="字段名称:" prop="name" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.name" clearable />
        </el-form-item>
        <el-form-item label="字段类型:" prop="fieldType" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerFieldForm.fieldType">
            <el-option v-for="i in Object.keys(fieldTypeObject)" :key="i" :label="fieldTypeObject[i]" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'string'"
          label="字段值:"
          prop="string"
          key="field-string"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.string" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'expression'"
          label="表达式:"
          prop="expression"
          key="field-expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.expression" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button size="small" @click="listenerFieldFormModelVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="saveListenerFiled">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
  import { ElMessageBox } from 'element-plus'
  import { createListenerObject, updateElementExtensions } from "../../utils";
  import { initListenerType, initListenerForm, listenerType, fieldType } from "./utilSelf";
  import { Plus } from '@element-plus/icons-vue'

  defineOptions({ name: 'ElementListeners' })

  const props = defineProps({
    id: String,
    type: String
  })
  const prefix = inject('prefix')
  const width = inject('width')

  const elementListenersList = ref<any[]>([]) // 监听器列表
  const listenerForm = ref<any>({}) // 监听器详情表单
  const listenerFormModelVisible = ref(false) // 监听器 编辑 侧边栏显示状态
  const fieldsListOfListener = ref<any[]>([])
  const listenerFieldForm = ref<any>({}) // 监听器 注入字段 详情表单
  const listenerFieldFormModelVisible = ref(false) // 监听器 注入字段表单弹窗 显示状态
  const editingListenerIndex = ref(-1) // 监听器所在下标,-1 为新增
  const editingListenerFieldIndex = ref(-1) // 字段所在下标,-1 为新增
  const listenerTypeObject = ref(listenerType)
  const fieldTypeObject = ref(fieldType)
  const bpmnElement = ref()
  const otherExtensionList = ref()
  const bpmnElementListeners = ref()
  const listenerFormRef = ref()
  const listenerFieldFormRef = ref()
  const bpmnInstances = () => (window as any)?.bpmnInstances

  watch(
    () => props.id,
    (val) => {
      val &&
        val.length &&
        nextTick(() => {
          resetListenersList()
        })
    },
    { immediate: true }
  )

  const resetListenersList = () => {
    bpmnElement.value = bpmnInstances().bpmnElement
    otherExtensionList.value = []
    bpmnElementListeners.value =
      bpmnElement.value.businessObject?.extensionElements?.values?.filter(
        (ex) => ex.$type === `${prefix}:ExecutionListener`
      ) ?? []
    elementListenersList.value = bpmnElementListeners.value.map((listener) =>
      initListenerType(listener)
    )
  }
  // 打开 监听器详情 侧边栏
  const openListenerForm = (listener, index?) => {
    if (listener) {
      listenerForm.value = initListenerForm(listener)
      editingListenerIndex.value = index
    } else {
      listenerForm.value = {}
      editingListenerIndex.value = -1 // 标记为新增
    }
    if (listener && listener.fields) {
      fieldsListOfListener.value = listener.fields.map((field) => ({
        ...field,
        fieldType: field.string ? 'string' : 'expression'
      }))
    } else {
      fieldsListOfListener.value = []
      listenerForm.value['fields'] = []
    }
    // 打开侧边栏并清楚验证状态
    listenerFormModelVisible.value = true
    nextTick(() => {
      if (listenerFormRef.value) {
        listenerFormRef.value.clearValidate()
      }
    })
  }
  // 打开监听器字段编辑弹窗
  const openListenerFieldForm = (field, index?) => {
    listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {}
    editingListenerFieldIndex.value = field ? index : -1
    listenerFieldFormModelVisible.value = true
    nextTick(() => {
      if (listenerFieldFormRef.value) {
        listenerFieldFormRef.value.clearValidate()
      }
    })
  }
  // 保存监听器注入字段
  const saveListenerFiled = async () => {
    let validateStatus = await listenerFieldFormRef.value.validate()
    if (!validateStatus) return // 验证不通过直接返回
    if (editingListenerFieldIndex.value === -1) {
      fieldsListOfListener.value.push(listenerFieldForm.value)
      listenerForm.value.fields.push(listenerFieldForm.value)
    } else {
      fieldsListOfListener.value.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
      listenerForm.value.fields.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
    }
    listenerFieldFormModelVisible.value = false
    nextTick(() => {
      listenerFieldForm.value = {}
    })
  }
  // 移除监听器字段
  const removeListenerField = (index) => {
    ElMessageBox.confirm('确认移除该字段吗?', '提示', {
      confirmButtonText: '确 认',
      cancelButtonText: '取 消'
    })
      .then(() => {
        fieldsListOfListener.value.splice(index, 1)
        listenerForm.value.fields.splice(index, 1)
      })
      .catch(() => console.info('操作取消'))
  }
  // 移除监听器
  const removeListener = (index) => {
    ElMessageBox.confirm('确认移除该监听器吗?', '提示', {
      confirmButtonText: '确 认',
      cancelButtonText: '取 消'
    })
      .then(() => {
        bpmnElementListeners.value.splice(index, 1)
        elementListenersList.value.splice(index, 1)
        updateElementExtensions(
          bpmnElement.value,
          otherExtensionList.value.concat(bpmnElementListeners.value)
        )
      })
      .catch(() => console.info('操作取消'))
  }
  // 保存监听器配置
  const saveListenerConfig = async () => {
    let validateStatus = await listenerFormRef.value.validate()
    if (!validateStatus) return // 验证不通过直接返回
    const listenerObject = createListenerObject(listenerForm.value, false, prefix)
    if (editingListenerIndex.value === -1) {
      bpmnElementListeners.value.push(listenerObject)
      elementListenersList.value.push(listenerForm.value)
    } else {
      bpmnElementListeners.value.splice(editingListenerIndex.value, 1, listenerObject)
      elementListenersList.value.splice(editingListenerIndex.value, 1, listenerForm.value)
    }
    // 保存其他配置
    otherExtensionList.value =
      bpmnElement.value.businessObject?.extensionElements?.values?.filter(
        (ex) => ex.$type !== `${prefix}:ExecutionListener`
      ) ?? []
    updateElementExtensions(
      bpmnElement.value,
      otherExtensionList.value.concat(bpmnElementListeners.value)
    )
    // 4. 隐藏侧边栏
    listenerFormModelVisible.value = false
    listenerForm.value = {}
  }

</script>

3、效果图如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1560278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础命令篇之——压缩与解压(tar、gzip、bzip2、zip和unzip)

linux基础命令——解压与压缩 以下是关于Linux命令tar、gzip、bzip2、zip和unzip的详细介绍&#xff1a; 1. tar 这个是Linux用的最多的解压缩命令 tar是Linux系统中用于创建和处理归档文件的命令。归档文件是一个包含多个文件和/或目录的单一文件。常与压缩命令gzip或bzip2结…

图像处理_积分图

目录 1. 积分图算法介绍 2. 基本原理 2.1 构建积分图 2.2 使用积分图 3. 举个例子 1. 积分图算法介绍 积分图算法是图像处理中的经典算法之一&#xff0c;由Crow在1984年首次提出&#xff0c;它是为了在多尺度透视投影中提高渲染速度。 积分图算法是一种快速计算图像区域和…

wavedec2函数及使用

在MATLAB中&#xff0c;进行小波分解及其逆运算是处理图像的一种常见方法&#xff0c;尤其适用于图像分析、压缩和去噪等场景。wavedec2函数可以对二维信号&#xff08;例如图像&#xff09;进行多级小波分解&#xff0c;而waverec2函数则用于进行相应的逆运算。以下是如何使用…

非NVIDIA平台下的CUDA的替代方案OpenCL,第一步如何获取PlatformInfo、DeviceInfo

非NVIDIA平台下的CUDA的替代方案OpenCL&#xff0c;第一步如何获取PlatformInfo、DeviceInfo 介绍 当谈到高性能计算&#xff0c;NVIDIA的CUDA框架无疑是一个强大的工具。OpenC&#xff08;Open Computing Language&#xff09;是一个更为通用的解决方案&#xff0c;或者你使用…

java 跳转搜索(Jump Search)

与二分搜索一样&#xff0c;跳转搜索是一种针对排序数组的搜索算法。基本思想是通过按固定步骤向前跳跃或跳过某些元素来代替搜索所有元素来检查更少的元素&#xff08;比线性搜索&#xff09;。例如&#xff0c;假设我们有一个大小为 n 的数组 arr[] 和一个大小为 m 的块&…

隐私计算实训营学习六:隐语PIR介绍及开发指南

文章目录 一、隐语实现的PIR总体介绍1.1 PIR的定义和种类1.2 隐语PIR功能分层 二、Index PIR-SealPIR介绍三、Keyword PIR- Labeled PSI介绍四、隐语PIR后续计划 一、隐语实现的PIR总体介绍 1.1 PIR的定义和种类 PIR(Private Information Retrieval PIR)隐匿查询&#xff1a;…

比亚迪的薪资。。。当年的迪子,今年的迪爹……

大家好&#xff0c;我是小黄。 俗话说金3银4&#xff0c;比亚迪一直都是一个相对热门的公司&#xff0c;“去年迪子&#xff0c;今年迪爹&#xff0c;去年座位空一大半&#xff0c;今年走廊都站满人……”这是很多应届毕业生对比亚迪的评价。 当年小黄毕业的时候&#xff0c;…

[计算机效率] 文件加密工具:Lockdir

3.11 文件加密工具&#xff1a;Lockdir Lockdir是一款安全性高、使用简单、体积极小的便携式文件夹加密器&#xff0c;无需安装&#xff0c;一键加密&#xff0c;一键解密&#xff0c;加密算法高&#xff0c;是优秀的加密工具。其主要特点包括&#xff1a; 加密操作简易&#…

hadoop-3.1.1分布式搭建与常用命令

一、准备工作 1.首先需要三台虚拟机&#xff1a; master 、 node1 、 node2 2.时间同步 ntpdate ntp.aliyun.com 3.调整时区 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 4.jdk1.8 java -version 5.修改主机名 三台分别执行 vim /etc/hostname 并将内容指定为…

酷开会员丨看、学、用、玩的智慧电视,酷开系统享你所想!

在数字化浪潮席卷之下&#xff0c;电视这个曾作为家庭娱乐设备中心的“客厅霸主”&#xff0c;在现代家庭中的地位似乎变得模糊起来。随着时代的发展&#xff0c;人们不再仅仅满足于电视观看节目的单一功能&#xff0c;而是期待电视能够提供更多元化、更智能的交互体验。考虑到…

[leetcode] 100. 相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true示例 2&a…

cookie介绍

文章目录 1.cookie是什么&#xff1f;2.cookie的存储位置3.什么是无状态问题&#xff0c;以及如何解决 4.存储在客户端的好处5.cookie的主要特点6.cookie的缺点7.cookie的产生过程8.cookie的使用步骤1.安装依赖2.引入依赖3.在中间件注册 9.cookie代码示例10.cookie的有效期 1.c…

电子级高纯PFA材质实验室器皿耗材PFA漏斗PFA试剂瓶PFA烧杯

PFA三角漏斗&#xff0c;整体均是PFA材质&#xff0c;无污染风险&#xff0c;可高压灭菌。 尺寸&#xff1a;外径40mm、160mm PFA三角漏斗 特点&#xff1a; 1、一体式成型&#xff0c;结构稳定&#xff1b; 2、化学耐受性强&#xff0c;耐受强酸、强碱以及各种有机溶剂&…

上位机图像处理和嵌入式模块部署(qmacvisual寻找圆和寻找直线)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面有几篇文章&#xff0c;我们谈到过直线拟合、圆拟合和椭圆拟合。当时&#xff0c;我们的做法是&#xff0c;先找到了轮廓&#xff0c;接着找到…

数据资产如何入表?有哪些步骤?

当下&#xff0c;数据资产入表这一关键环节对于企业的高效运营与决策制定具有至关重要的作用。软信天成团队经过长期研究与实践&#xff0c;将数据资产入表的全流程归纳总结为四个核心步骤&#xff0c;以期为诸位提供帮忙。 &#xff08;一&#xff09;确保数据合规&#xff0…

8.均值滤波

1 简介 均值滤波是一种低通滤波&#xff0c;它可以有效过滤图片中的椒盐噪声&#xff0c;但是副作用也同样明显&#xff0c;会使图片的边缘过于模糊。   均值滤波的卷积核系数均为1。   这里最终重复一下算法实现以及验证的步骤&#xff1a;     1.MATLAB读取图片并转化…

JVM实战之性能调优[2](线程转储案例认识和分析)

文章目录 版权声明案例1&#xff1a;CPU占用率高问题问题描述解决思路补充内容 案例2&#xff1a;接口响应时间长问题问题描述解决思路Arthas trace命令Arthas watch命令解决问题 案例3&#xff1a;定位偏底层性能问题问题描述解决思路&#xff1a;Arthas火焰图问题解决 案例4&…

高级DBA带你处理MySQL客户端程序频繁访问MYSQL数据库并错误链接不释放导致连接数爆满事故实战

高级DBA带你处理MySQL客户端程序频繁访问MYSQL数据库并错误链接不释放导致连接数爆满事故实战 一、生产事故描述 Mysql生产数据库最大连接数爆满&#xff0c;其余客户端也同样拿不到数据库连接&#xff0c;生产异常&#xff0c;数据传输失败&#xff01; 报错如下&#xff1a…

有趣的css - 文字下划线条动画按钮

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是用 css 实现文字下划线条动画按钮。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页…

【WEEK5】 【DAY5】DML语言【中文版】

2024.3.29 Friday 目录 3.DML语言3.1.外键&#xff08;了解&#xff09;3.1.1.概念3.1.2.作用3.1.3.添加&#xff08;书写&#xff09;外键的几种方法3.1.3.1.创建表时直接在主动引用的表里写&#xff08;被引用的表的被引用的部分&#xff09;3.1.3.2.先创建表后修改表以添加…