<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" :formatter="formatterEvent" />
|
<el-table-column label="监听器类型" min-width="100px" show-overflow-tooltip :formatter="formatterListener" />
|
<el-table-column label="操作" width="90px">
|
<template v-slot="{ row, $index }">
|
<el-button link type="primary" @click="openListenerForm(row, $index)">编辑</el-button>
|
<el-button link type="danger" @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`"
|
class="listener-drawer"
|
append-to-body
|
destroy-on-close>
|
<el-form :model="listenerForm" label-width="96px" ref="listenerFormRef" @submit.prevent>
|
<el-form-item label="事件类型" prop="event" :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择事件类型' }">
|
<el-select v-model="listenerForm.event">
|
<el-option v-for="item in EXECUTION_EVENT_TYPE" :key="item.value" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="监听器类型" prop="listenerType" :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择监听器类型' }">
|
<el-input
|
v-model="listenerForm[selectedProp]"
|
clearable
|
class="input-with-select">
|
<template #prepend>
|
<el-select v-model="listenerForm.listenerType" style="width: 100%">
|
<el-option v-for="item in LISTENER_TYPE" :key="item.key" :label="item.label" :value="item.value" />
|
</el-select>
|
</template>
|
<template #append>
|
<el-button :icon="Search" />
|
</template>
|
</el-input>
|
</el-form-item>
|
<template v-for="item in LISTENER_TYPEWithoutJB">
|
<el-form-item
|
v-if="listenerForm.listenerType === item.value"
|
:key="item.key"
|
:label="item.label"
|
:prop="item.prop"
|
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
>
|
<el-input v-model="listenerForm[item.prop]" clearable />
|
</el-form-item>
|
</template>
|
<!-- 脚本类型 -->
|
<!-- <template v-if="listenerForm.listenerType === LISTENER_TYPE[LISTENER_TYPE.length - 1].value">-->
|
<!-- <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 v-for="item in SCRIPT_TYPE" :key="item.value" :label="item.label" :value="item.value" />-->
|
<!-- </el-select>-->
|
<!-- </el-form-item>-->
|
<!-- <el-form-item-->
|
<!-- v-if="listenerForm.scriptType === SCRIPT_TYPE[0].value"-->
|
<!-- 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 === SCRIPT_TYPE[1].value"-->
|
<!-- 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 />
|
<div class="listener-filed__title">
|
<span><el-icon><Menu /></el-icon>注入字段:</span>
|
<el-button size="small" type="primary" @click="openListenerFieldForm(null)">添加字段</el-button>
|
</div>
|
<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="formatterField" />
|
<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="primary" @click="openListenerFieldForm(row, $index)">编辑</el-button>
|
<el-button link type="danger" @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'], message: '请填写字段名称' }">
|
<el-input v-model="listenerFieldForm.name" clearable />
|
</el-form-item>
|
<el-form-item label="字段类型:" prop="fieldType" :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择字段类型' }">
|
<el-select v-model="listenerFieldForm.fieldType">
|
<el-option v-for="item in FIELD_TYPE" :key="item.value" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
v-if="listenerFieldForm.fieldType === FIELD_TYPE[0].value"
|
label="字段值:"
|
prop="string"
|
key="field-string"
|
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写字段值' }"
|
>
|
<el-input v-model="listenerFieldForm.string" clearable />
|
</el-form-item>
|
<el-form-item
|
v-if="listenerFieldForm.fieldType === FIELD_TYPE[1].value"
|
label="表达式:"
|
prop="expression"
|
key="field-expression"
|
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写表达式' }"
|
>
|
<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,
|
EXECUTION_EVENT_TYPE,
|
LISTENER_TYPE,
|
FIELD_TYPE,
|
SCRIPT_TYPE,
|
EVENT_DEFINITION_TYPE
|
} from "./utilSelf";
|
import { Plus, Search } from "@element-plus/icons-vue";
|
|
export default {
|
name: "ElementListeners",
|
setup() {
|
return { Plus, Search }
|
},
|
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 为新增
|
};
|
},
|
watch: {
|
id: {
|
immediate: true,
|
handler(val) {
|
val && val.length && this.$nextTick(() => this.resetListenersList());
|
}
|
}
|
},
|
computed: {
|
EXECUTION_EVENT_TYPE() { return EXECUTION_EVENT_TYPE },
|
LISTENER_TYPE() { return LISTENER_TYPE },
|
FIELD_TYPE() { return FIELD_TYPE },
|
SCRIPT_TYPE() { return SCRIPT_TYPE },
|
EVENT_DEFINITION_TYPE() { return EVENT_DEFINITION_TYPE },
|
formatterEvent() {
|
return (row) => {
|
return EXECUTION_EVENT_TYPE.find(find => find.value === row.event)?.label || ""
|
}
|
},
|
formatterListener() {
|
return (row) => {
|
return LISTENER_TYPE.find(find => find.value === row.listener)?.label || ""
|
}
|
},
|
formatterField() {
|
return (row) => {
|
return FIELD_TYPE.find(find => find.value === row.fieldType)?.label || ""
|
}
|
},
|
selectedProp() {
|
return LISTENER_TYPE.find(find => find.value === this.listenerForm.listenerType)?.prop || ''
|
}
|
},
|
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>
|