修改flowable
parent
73f42a722d
commit
72cf76c249
|
@ -19,43 +19,43 @@
|
|||
<my-process-penal :bpmn-modeler="modeler" :prefix="controlForm.prefix" class="process-panel" />
|
||||
|
||||
<!-- demo config -->
|
||||
<!-- <div class="demo-control-bar">-->
|
||||
<!-- <div class="open-model-button" @click="controlDrawerVisible = true"><el-icon><setting /></el-icon></div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-drawer v-model="controlDrawerVisible" size="400px" title="偏好设置" append-to-body destroy-on-close>-->
|
||||
<!-- <el-form :model="controlForm" size="small" label-width="100px" class="control-form" @submit.prevent>-->
|
||||
<!-- <el-form-item label="流程ID">-->
|
||||
<!-- <el-input v-model="controlForm.processId" @change="reloadProcessDesigner(true)" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="流程名称">-->
|
||||
<!-- <el-input v-model="controlForm.processName" @change="reloadProcessDesigner(true)" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="流转模拟">-->
|
||||
<!-- <el-switch v-model="controlForm.simulation" inactive-text="停用" active-text="启用" @change="reloadProcessDesigner()" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="禁用双击">-->
|
||||
<!-- <el-switch v-model="controlForm.labelEditing" inactive-text="停用" active-text="启用" @change="changeLabelEditingStatus" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="自定义渲染">-->
|
||||
<!-- <el-switch v-model="controlForm.labelVisible" inactive-text="停用" active-text="启用" @change="changeLabelVisibleStatus" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="流程引擎">-->
|
||||
<!-- <el-radio-group v-model="controlForm.prefix" @change="reloadProcessDesigner()">-->
|
||||
<!-- <el-radio label="camunda">camunda</el-radio>-->
|
||||
<!-- <el-radio label="flowable">flowable</el-radio>-->
|
||||
<!-- <el-radio label="activiti">activiti</el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="工具栏">-->
|
||||
<!-- <el-radio-group v-model="controlForm.headerButtonSize">-->
|
||||
<!-- <el-radio label="small">small</el-radio>-->
|
||||
<!-- <el-radio label="default">default</el-radio>-->
|
||||
<!-- <el-radio label="large">large</el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-switch v-model="pageMode" active-text="dark" inactive-text="light" @change="changePageMode"></el-switch>-->
|
||||
<!-- </el-form>-->
|
||||
<!-- </el-drawer>-->
|
||||
<div class="demo-control-bar">
|
||||
<div class="open-model-button" @click="controlDrawerVisible = true"><el-icon><setting /></el-icon></div>
|
||||
</div>
|
||||
<el-drawer v-model="controlDrawerVisible" size="400px" title="偏好设置" append-to-body destroy-on-close>
|
||||
<el-form :model="controlForm" size="small" label-width="100px" class="control-form" @submit.prevent>
|
||||
<el-form-item label="流程ID">
|
||||
<el-input v-model="controlForm.processId" @change="reloadProcessDesigner(true)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程名称">
|
||||
<el-input v-model="controlForm.processName" @change="reloadProcessDesigner(true)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流转模拟">
|
||||
<el-switch v-model="controlForm.simulation" inactive-text="停用" active-text="启用" @change="reloadProcessDesigner()" />
|
||||
</el-form-item>
|
||||
<el-form-item label="禁用双击">
|
||||
<el-switch v-model="controlForm.labelEditing" inactive-text="停用" active-text="启用" @change="changeLabelEditingStatus" />
|
||||
</el-form-item>
|
||||
<el-form-item label="自定义渲染">
|
||||
<el-switch v-model="controlForm.labelVisible" inactive-text="停用" active-text="启用" @change="changeLabelVisibleStatus" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程引擎">
|
||||
<el-radio-group v-model="controlForm.prefix" @change="reloadProcessDesigner()">
|
||||
<el-radio label="camunda">camunda</el-radio>
|
||||
<el-radio label="flowable">flowable</el-radio>
|
||||
<el-radio label="activiti">activiti</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="工具栏">
|
||||
<el-radio-group v-model="controlForm.headerButtonSize">
|
||||
<el-radio label="small">small</el-radio>
|
||||
<el-radio label="default">default</el-radio>
|
||||
<el-radio label="large">large</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-switch v-model="pageMode" active-text="dark" inactive-text="light" @change="changePageMode"></el-switch>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #content>
|
||||
<el-button :size="headerButtonSize" type="text" @click="previewProcessXML">预览XML</el-button>
|
||||
<br />
|
||||
<el-button :size="headerButtonSize" type="text" @click="previewProcessJson">预览JSON</el-button>
|
||||
<!-- <el-button :size="headerButtonSize" type="text" @click="previewProcessJson">预览JSON</el-button> -->
|
||||
</template>
|
||||
<el-button :size="headerButtonSize" :type="headerButtonType" :icon="View">预览</el-button>
|
||||
</el-tooltip>
|
||||
|
@ -111,8 +111,7 @@ import camundaModdleExtension from './plugins/extension-moddle/camunda';
|
|||
import activitiModdleExtension from './plugins/extension-moddle/activiti';
|
||||
import flowableModdleExtension from './plugins/extension-moddle/flowable';
|
||||
// 引入json转换与高亮
|
||||
// import convert from "xml-js";
|
||||
import X2JS from "x2js";
|
||||
// import X2JS from "x2js";
|
||||
|
||||
import Codemirror from 'codemirror-editor-vue3';
|
||||
import 'codemirror/theme/monokai.css'
|
||||
|
@ -497,23 +496,18 @@ export default {
|
|||
});
|
||||
},
|
||||
previewProcessJson() {
|
||||
// const newConvert = new X2JS();
|
||||
// this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
|
||||
// this.previewResult = convert.xml2json(xml, { spaces: 2 });
|
||||
// const { definitions } = newConvert.xml2js(xml);
|
||||
// if (definitions) {
|
||||
// this.previewResult = JSON.stringify(definitions, null, 4);
|
||||
// } else {
|
||||
// this.previewResult = "";
|
||||
// }
|
||||
|
||||
// this.previewType = "json";
|
||||
// this.previewModelVisible = true;
|
||||
// });
|
||||
const newConvert = new X2JS();
|
||||
this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
|
||||
const { definitions } = newConvert.xml2js(xml);
|
||||
if (definitions) {
|
||||
this.previewResult = JSON.stringify(definitions, null, 4);
|
||||
} else {
|
||||
this.previewResult = "";
|
||||
}
|
||||
|
||||
this.previewType = "json";
|
||||
this.previewModelVisible = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -319,21 +319,6 @@
|
|||
"name": "priority",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "dataType",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "text",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "deptId",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
</el-collapse-item>
|
||||
<el-collapse-item name="condition" v-if="formVisible" key="form">
|
||||
<template #title>
|
||||
|
||||
<div class="panel-tab__title"><el-icon><list /></el-icon>表单</div>
|
||||
</template>
|
||||
<element-form :id="elementId" :type="elementType" />
|
||||
|
@ -37,20 +38,23 @@
|
|||
</template>
|
||||
<element-multi-instance :business-object="elementBusinessObject" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="taskListeners" v-if="elementType === 'UserTask'" key="taskListeners">
|
||||
<template #title>
|
||||
<div class="panel-tab__title"><el-icon><bell-filled /></el-icon>任务监听器</div>
|
||||
</template>
|
||||
<user-task-listeners :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="listeners" key="listeners">
|
||||
<template #title>
|
||||
|
||||
<div class="panel-tab__title"><el-icon><bell-filled /></el-icon>执行监听器</div>
|
||||
</template>
|
||||
<element-listeners :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="taskListeners" v-if="elementType === 'UserTask'" key="taskListeners">
|
||||
<template #title>
|
||||
|
||||
<div class="panel-tab__title"><el-icon><bell-filled /></el-icon>任务监听器</div>
|
||||
</template>
|
||||
<user-task-listeners :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="extensions" key="extensions">
|
||||
<template #title>
|
||||
|
||||
<div class="panel-tab__title"><el-icon><circle-plus /></el-icon>扩展属性</div>
|
||||
</template>
|
||||
<element-properties :id="elementId" :type="elementType" />
|
||||
|
|
|
@ -1,155 +1,128 @@
|
|||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<el-form size="small" label-width="80px" @submit.prevent>
|
||||
<el-form-item label="表单" prop="formKey">
|
||||
<el-select v-model="formKey" placeholder="请选择表单" @change="updateElementFormKey" clearable>
|
||||
<el-option v-for="item in formOptions" :key="item.formId" :label="item.formName" :value="`key_${item.formId}`" />
|
||||
<el-form-item label="表单标识">
|
||||
<el-input v-model="formKey" clearable @change="updateElementFormKey" />
|
||||
</el-form-item>
|
||||
<el-form-item label="业务标识">
|
||||
<el-select v-model="businessKey" @change="updateElementBusinessKey">
|
||||
<el-option v-for="i in fieldList" :key="i.id" :value="i.id" :label="i.label" />
|
||||
<el-option label="无" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="localScope">
|
||||
<template #label>
|
||||
<div class="flex align-center">
|
||||
<el-tooltip content="若为节点表单,则表单信息仅在此节点可用,默认为全局表单,表单信息在整个流程实例中可用" placement="top-start">
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
<span>节点表单</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-switch
|
||||
:disabled="type === 'StartEvent'"
|
||||
v-model="localScope"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
@change="updateElementFormScope()"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="表单标识">-->
|
||||
<!-- <el-input v-model="formKey" clearable @change="updateElementFormKey" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="业务标识">-->
|
||||
<!-- <el-select v-model="businessKey" @change="updateElementBusinessKey">-->
|
||||
<!-- <el-option v-for="i in fieldList" :key="i.id" :value="i.id" :label="i.label" />-->
|
||||
<!-- <el-option label="无" value="" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
|
||||
<!--字段列表-->
|
||||
<!-- <div class="element-property list-property">-->
|
||||
<!-- <el-divider><el-icon><coin /></el-icon> 表单字段</el-divider>-->
|
||||
<!-- <el-table :data="fieldList" size="small" max-height="240" border fit>-->
|
||||
<!-- <el-table-column label="序号" type="index" width="50px" />-->
|
||||
<!-- <el-table-column label="字段名称" prop="label" min-width="80px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="字段类型" prop="type" min-width="80px" :formatter="row => fieldType[row.type] || row.type" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="默认值" prop="defaultValue" min-width="80px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="操作" width="90px">-->
|
||||
<!-- <template v-slot="{ row, $index }">-->
|
||||
<!-- <el-button link type="" @click="openFieldForm(row, $index)">编辑</el-button>-->
|
||||
<!-- <el-divider direction="vertical" />-->
|
||||
<!-- <el-button link type="" style="color: #ff4d4f" @click="removeField(row, $index)">移除</el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- </el-table>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="element-drawer__button">-->
|
||||
<!-- <el-button size="small" type="primary" :icon="Plus" @click="openFieldForm(null, -1)">添加字段</el-button>-->
|
||||
<!-- </div>-->
|
||||
<div class="element-property list-property">
|
||||
<el-divider><el-icon><coin /></el-icon> 表单字段</el-divider>
|
||||
<el-table :data="fieldList" size="small" max-height="240" border fit>
|
||||
<el-table-column label="序号" type="index" width="50px" />
|
||||
<el-table-column label="字段名称" prop="label" min-width="80px" show-overflow-tooltip />
|
||||
<el-table-column label="字段类型" prop="type" min-width="80px" :formatter="row => fieldType[row.type] || row.type" show-overflow-tooltip />
|
||||
<el-table-column label="默认值" prop="defaultValue" min-width="80px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-button link type="" @click="openFieldForm(row, $index)">编辑</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link type="" style="color: #ff4d4f" @click="removeField(row, $index)">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="element-drawer__button">
|
||||
<el-button size="small" type="primary" :icon="Plus" @click="openFieldForm(null, -1)">添加字段</el-button>
|
||||
</div>
|
||||
|
||||
<!--字段配置侧边栏-->
|
||||
<!-- <el-drawer v-model="fieldModelVisible" title="字段配置" :size="`${width}px`" append-to-body destroy-on-close>-->
|
||||
<!-- <el-form :model="formFieldForm" label-width="90px" size="small" @submit.prevent>-->
|
||||
<!-- <el-form-item label="字段ID">-->
|
||||
<!-- <el-input v-model="formFieldForm.id" clearable />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="类型">-->
|
||||
<!-- <el-select v-model="formFieldForm.typeType" placeholder="请选择字段类型" clearable @change="changeFieldTypeType">-->
|
||||
<!-- <el-option v-for="(value, key) of fieldType" :key="key" :label="value" :value="key" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item v-if="formFieldForm.typeType === 'custom'" label="类型名称">-->
|
||||
<!-- <el-input v-model="formFieldForm.type" clearable />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="名称">-->
|
||||
<!-- <el-input v-model="formFieldForm.label" clearable />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item v-if="formFieldForm.typeType === 'date'" label="时间格式">-->
|
||||
<!-- <el-input v-model="formFieldForm.datePattern" clearable />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="默认值">-->
|
||||
<!-- <el-input v-model="formFieldForm.defaultValue" clearable />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-form>-->
|
||||
<el-drawer v-model="fieldModelVisible" title="字段配置" :size="`${width}px`" append-to-body destroy-on-close>
|
||||
<el-form :model="formFieldForm" label-width="90px" size="small" @submit.prevent>
|
||||
<el-form-item label="字段ID">
|
||||
<el-input v-model="formFieldForm.id" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="formFieldForm.typeType" placeholder="请选择字段类型" clearable @change="changeFieldTypeType">
|
||||
<el-option v-for="(value, key) of fieldType" :key="key" :label="value" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formFieldForm.typeType === 'custom'" label="类型名称">
|
||||
<el-input v-model="formFieldForm.type" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="名称">
|
||||
<el-input v-model="formFieldForm.label" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formFieldForm.typeType === 'date'" label="时间格式">
|
||||
<el-input v-model="formFieldForm.datePattern" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="默认值">
|
||||
<el-input v-model="formFieldForm.defaultValue" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 枚举值设置 -->
|
||||
<!-- <template v-if="formFieldForm.type === 'enum'">-->
|
||||
<!-- <el-divider key="enum-divider" />-->
|
||||
<!-- <p key="enum-title" class="listener-filed__title">-->
|
||||
<!-- <span>-->
|
||||
<!-- <el-icon>-->
|
||||
<!-- <menu />-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- 枚举值列表:-->
|
||||
<!-- </span>-->
|
||||
<!-- <el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'enum')">添加枚举值</el-button>-->
|
||||
<!-- </p>-->
|
||||
<!-- <el-table key="enum-table" :data="fieldEnumList" size="small" max-height="240" border fit>-->
|
||||
<!-- <el-table-column label="序号" width="50px" type="index" />-->
|
||||
<!-- <el-table-column label="枚举值编号" prop="id" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="枚举值名称" prop="name" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="操作" width="90px">-->
|
||||
<!-- <template v-slot="{ row, $index }">-->
|
||||
<!-- <el-button link type="" @click="openFieldOptionForm(row, $index, 'enum')">编辑</el-button>-->
|
||||
<!-- <el-divider direction="vertical" />-->
|
||||
<!-- <el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'enum')">移除</el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- </el-table>-->
|
||||
<!-- </template>-->
|
||||
<template v-if="formFieldForm.type === 'enum'">
|
||||
<el-divider key="enum-divider" />
|
||||
<p key="enum-title" class="listener-filed__title">
|
||||
<span><el-icon><menu /></el-icon>枚举值列表:</span>
|
||||
<el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'enum')">添加枚举值</el-button>
|
||||
</p>
|
||||
<el-table key="enum-table" :data="fieldEnumList" size="small" max-height="240" border fit>
|
||||
<el-table-column label="序号" width="50px" type="index" />
|
||||
<el-table-column label="枚举值编号" prop="id" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="枚举值名称" prop="name" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-button link type="" @click="openFieldOptionForm(row, $index, 'enum')">编辑</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'enum')">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<!-- 校验规则 -->
|
||||
<!-- <el-divider key="validation-divider" />-->
|
||||
<!-- <p key="validation-title" class="listener-filed__title">-->
|
||||
<!-- <span><el-icon><menu /></el-icon>约束条件列表:</span>-->
|
||||
<!-- <el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'constraint')">添加约束</el-button>-->
|
||||
<!-- </p>-->
|
||||
<!-- <el-table key="validation-table" :data="fieldConstraintsList" size="small" max-height="240" border fit>-->
|
||||
<!-- <el-table-column label="序号" width="50px" type="index" />-->
|
||||
<!-- <el-table-column label="约束名称" prop="name" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="约束配置" prop="config" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="操作" width="90px">-->
|
||||
<!-- <template v-slot="{ row, $index }">-->
|
||||
<!-- <el-button link type="" @click="openFieldOptionForm(row, $index, 'constraint')">编辑</el-button>-->
|
||||
<!-- <el-divider direction="vertical" />-->
|
||||
<!-- <el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'constraint')">移除</el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- </el-table>-->
|
||||
<el-divider key="validation-divider" />
|
||||
<p key="validation-title" class="listener-filed__title">
|
||||
<span><el-icon><menu /></el-icon>约束条件列表:</span>
|
||||
<el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'constraint')">添加约束</el-button>
|
||||
</p>
|
||||
<el-table key="validation-table" :data="fieldConstraintsList" size="small" max-height="240" border fit>
|
||||
<el-table-column label="序号" width="50px" type="index" />
|
||||
<el-table-column label="约束名称" prop="name" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="约束配置" prop="config" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-button link type="" @click="openFieldOptionForm(row, $index, 'constraint')">编辑</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'constraint')">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 表单属性 -->
|
||||
<!-- <el-divider key="property-divider" />-->
|
||||
<!-- <p key="property-title" class="listener-filed__title">-->
|
||||
<!-- <span><el-icon><menu /></el-icon>字段属性列表:</span>-->
|
||||
<!-- <el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'property')">添加属性</el-button>-->
|
||||
<!-- </p>-->
|
||||
<!-- <el-table key="property-table" :data="fieldPropertiesList" size="small" max-height="240" border fit>-->
|
||||
<!-- <el-table-column label="序号" width="50px" type="index" />-->
|
||||
<!-- <el-table-column label="属性编号" prop="id" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />-->
|
||||
<!-- <el-table-column label="操作" width="90px">-->
|
||||
<!-- <template v-slot="{ row, $index }">-->
|
||||
<!-- <el-button link type="" @click="openFieldOptionForm(row, $index, 'property')">编辑</el-button>-->
|
||||
<!-- <el-divider direction="vertical" />-->
|
||||
<!-- <el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'property')">移除</el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- </el-table>-->
|
||||
<el-divider key="property-divider" />
|
||||
<p key="property-title" class="listener-filed__title">
|
||||
<span><el-icon><menu /></el-icon>字段属性列表:</span>
|
||||
<el-button size="small" type="primary" @click="openFieldOptionForm(null, -1, 'property')">添加属性</el-button>
|
||||
</p>
|
||||
<el-table key="property-table" :data="fieldPropertiesList" size="small" max-height="240" border fit>
|
||||
<el-table-column label="序号" width="50px" type="index" />
|
||||
<el-table-column label="属性编号" prop="id" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-button link type="" @click="openFieldOptionForm(row, $index, 'property')">编辑</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link type="" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'property')">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<!-- <div class="element-drawer__button">-->
|
||||
<!-- <el-button size="small">取 消</el-button>-->
|
||||
<!-- <el-button size="small" type="primary" @click="saveField">保 存</el-button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-drawer>-->
|
||||
<div class="element-drawer__button">
|
||||
<el-button size="small">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="saveField">保 存</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog v-model="fieldOptionModelVisible" :title="optionModelTitle" width="600px" append-to-body destroy-on-close>
|
||||
<el-form :model="fieldOptionForm" size="small" label-width="96px" @submit.prevent>
|
||||
|
@ -176,8 +149,6 @@
|
|||
|
||||
<script>
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { listAllForm } from "@/api/workflow/form";
|
||||
|
||||
export default {
|
||||
name: 'ElementForm',
|
||||
setup() {
|
||||
|
@ -196,8 +167,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
formKey: '',
|
||||
formOptions: [],
|
||||
localScope: false,
|
||||
businessKey: '',
|
||||
optionModelTitle: '',
|
||||
fieldList: [],
|
||||
|
@ -229,50 +198,38 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
/** 查询流程分类列表 */
|
||||
this.getFormList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询表单列表 */
|
||||
getFormList() {
|
||||
listAllForm().then(response => this.formOptions = response.data)
|
||||
},
|
||||
resetFormList() {
|
||||
this.bpmnELement = window.bpmnInstances.bpmnElement;
|
||||
this.formKey = this.bpmnELement.businessObject.formKey;
|
||||
this.localScope = this.bpmnELement.businessObject.localScope;
|
||||
// 获取元素扩展属性 或者 创建扩展属性
|
||||
this.elExtensionElements =
|
||||
this.bpmnELement.businessObject.get('extensionElements') || window.bpmnInstances.moddle.create('bpmn:ExtensionElements', { values: [] });
|
||||
// 获取元素表单配置 或者 创建新的表单配置
|
||||
// try {
|
||||
// this.formData =
|
||||
// this.elExtensionElements.values.filter(ex => ex.$type === `${this.prefix}:FormData`)[0] ||
|
||||
// window.bpmnInstances.moddle.create(`${this.prefix}:FormData`, { fields: [] });
|
||||
// } catch (error) {
|
||||
// this.formData = {}
|
||||
// console.log(error)
|
||||
// }
|
||||
try {
|
||||
this.formData =
|
||||
this.elExtensionElements.values.filter(ex => ex.$type === `${this.prefix}:FormData`)[0] ||
|
||||
window.bpmnInstances.moddle.create(`${this.prefix}:FormData`, { fields: [] });
|
||||
} catch (error) {
|
||||
this.formData = {}
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
// 业务标识 businessKey, 绑定在 formData 中
|
||||
// this.businessKey = this.formData.businessKey;
|
||||
this.businessKey = this.formData.businessKey;
|
||||
|
||||
// 保留剩余扩展元素,便于后面更新该元素对应属性
|
||||
this.otherExtensions = this.elExtensionElements.values.filter(ex => ex.$type !== `${this.prefix}:FormData`);
|
||||
|
||||
// 复制原始值,填充表格
|
||||
// this.fieldList = JSON.parse(JSON.stringify(this.formData.fields || []));
|
||||
this.fieldList = JSON.parse(JSON.stringify(this.formData.fields || []));
|
||||
|
||||
// 更新元素扩展属性,避免后续报错
|
||||
// this.updateElementExtensions();
|
||||
this.updateElementExtensions();
|
||||
},
|
||||
updateElementFormKey() {
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { formKey: this.formKey });
|
||||
},
|
||||
updateElementFormScope() {
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { localScope: this.localScope });
|
||||
},
|
||||
updateElementBusinessKey() {
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnELement, this.formData, { businessKey: this.businessKey });
|
||||
},
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
<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="80px" show-overflow-tooltip :formatter="formatterEvent" />
|
||||
<!-- <el-table-column label="事件id" min-width="80px" prop="id" show-overflow-tooltip />-->
|
||||
<el-table-column label="监听器类型" min-width="80px" show-overflow-tooltip :formatter="formatterListener" />
|
||||
<el-table-column label="事件类型" min-width="80px" show-overflow-tooltip :formatter="row => listenerEventTypeObject[row.event]" />
|
||||
<el-table-column label="事件id" min-width="80px" prop="id" show-overflow-tooltip />
|
||||
<el-table-column label="监听器类型" min-width="80px" show-overflow-tooltip :formatter="row => listenerTypeObject[row.listenerType]" />
|
||||
<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>
|
||||
<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>
|
||||
|
@ -17,79 +18,95 @@
|
|||
</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" style="width: 100%">
|
||||
<el-option v-for="item in TASK_EVENT_TYPE" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<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 v-for="i in Object.keys(listenerEventTypeObject)" :key="i" :label="listenerEventTypeObject[i]" :value="i" />
|
||||
</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-form-item label="监听器ID" prop="id" :rules="{ required: true, trigger: ['blur', 'change'] }">
|
||||
<el-input v-model="listenerForm.id" clearable />
|
||||
</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>
|
||||
<template #append>
|
||||
<el-button :icon="Search" />
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
</el-form-item>
|
||||
<!-- 脚本类型 -->
|
||||
<!-- <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>-->
|
||||
<!-- 监听事件: 超时 -->
|
||||
<template v-if="listenerForm.event === TASK_EVENT_TYPE[TASK_EVENT_TYPE.length - 1].value">
|
||||
<template v-if="listenerForm.event === 'timeout'">
|
||||
<el-form-item label="定时器类型" prop="eventDefinitionType" key="eventDefinitionType">
|
||||
<el-select v-model="listenerForm.eventDefinitionType">
|
||||
<el-option v-for="item in EVENT_DEFINITION_TYPE" :key="item.value" :value="item.value" :label="item.label" />
|
||||
<el-option label="日期" value="date" />
|
||||
<el-option label="持续时长" value="duration" />
|
||||
<el-option label="循环" value="cycle" />
|
||||
<el-option label="无" value="null" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
@ -103,79 +120,73 @@
|
|||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<el-divider />
|
||||
<div class="listener-filed__title">
|
||||
<p class="listener-filed__title">
|
||||
<span><el-icon><Menu /></el-icon>注入字段:</span>
|
||||
<el-button size="small" type="primary" @click="openListenerFieldForm(null)">添加字段</el-button>
|
||||
</div>
|
||||
</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="formatterField" />
|
||||
<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="primary" @click="openListenerFieldForm(row, $index)">编辑</el-button>
|
||||
<el-button link type="danger" @click="removeListenerField(row, $index)">移除</el-button>
|
||||
<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 @click="listenerFormModelVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveListenerConfig">保 存</el-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-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'], message: '请选择字段类型' }">
|
||||
<el-form-item label="字段类型:" prop="fieldType" :rules="{ required: true, trigger: ['blur', 'change'] }">
|
||||
<el-select v-model="listenerFieldForm.fieldType">
|
||||
<el-option v-for="item in FIELD_TYPE" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<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 === FIELD_TYPE[0].value"
|
||||
v-if="listenerFieldForm.fieldType === 'string'"
|
||||
label="字段值:"
|
||||
prop="string"
|
||||
key="field-string"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写字段值' }"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.string" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerFieldForm.fieldType === FIELD_TYPE[1].value"
|
||||
v-if="listenerFieldForm.fieldType === 'expression'"
|
||||
label="表达式:"
|
||||
prop="expression"
|
||||
key="field-expression"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写表达式' }"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.expression" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="listenerFieldFormModelVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveListenerFiled">确 定</el-button>
|
||||
<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 {
|
||||
initListenerForm,
|
||||
initListenerType,
|
||||
FIELD_TYPE,
|
||||
LISTENER_TYPE,
|
||||
TASK_EVENT_TYPE,
|
||||
SCRIPT_TYPE,
|
||||
EVENT_DEFINITION_TYPE
|
||||
} from "./utilSelf";
|
||||
import { Plus, Search } from '@element-plus/icons-vue'
|
||||
import { initListenerForm, initListenerType, eventType, listenerType, fieldType } from "./utilSelf";
|
||||
|
||||
export default {
|
||||
name: "UserTaskListeners",
|
||||
props: {
|
||||
|
@ -186,14 +197,14 @@ export default {
|
|||
prefix: "prefix",
|
||||
width: "width"
|
||||
},
|
||||
setup() {
|
||||
return { Plus, Search }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
elementListenersList: [],
|
||||
listenerEventTypeObject: eventType,
|
||||
listenerTypeObject: listenerType,
|
||||
listenerFormModelVisible: false,
|
||||
listenerForm: {},
|
||||
fieldTypeObject: fieldType,
|
||||
fieldsListOfListener: [],
|
||||
listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
|
||||
editingListenerIndex: -1, // 监听器所在下标,-1 为新增
|
||||
|
@ -209,31 +220,6 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
TASK_EVENT_TYPE() { return TASK_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 TASK_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;
|
||||
|
|
|
@ -40,41 +40,23 @@ export function initListenerType(listener) {
|
|||
};
|
||||
}
|
||||
|
||||
// 监听类型
|
||||
export const LISTENER_TYPE = [
|
||||
{ label: "Java 类", value: "classListener", prop: "class", key: "listener-class" },
|
||||
{ label: "表达式", value: "expressionListener", prop: "expression", key: "listener-expression" },
|
||||
{ label: "代理表达式", value: "delegateExpressionListener", prop: "delegateExpression", key: "listener-delegate" },
|
||||
// { label: "脚本", value: "scriptListener", prop: "scriptFormat", key: "listener-script-format" },
|
||||
]
|
||||
// 脚本类型
|
||||
export const SCRIPT_TYPE = [
|
||||
{ label: "内联脚本", value: "inlineScript" },
|
||||
{ label: "外部脚本", value: "externalScript" },
|
||||
]
|
||||
// 任务监听器: 事件类型
|
||||
export const TASK_EVENT_TYPE = [
|
||||
{ label: "创建", value: "create" },
|
||||
{ label: "指派", value: "assignment" },
|
||||
{ label: "完成", value: "complete" },
|
||||
{ label: "删除", value: "delete" },
|
||||
{ label: "更新", value: "update" },
|
||||
{ label: "超时", value: "timeout" },
|
||||
]
|
||||
// 执行监听器: 事件类型
|
||||
export const EXECUTION_EVENT_TYPE = [
|
||||
{ label: "开始", value: "start" },
|
||||
{ label: "结束", value: "end" },
|
||||
]
|
||||
// 事件类型: 定时器类型
|
||||
export const EVENT_DEFINITION_TYPE = [
|
||||
{ label: "无", value: "null" },
|
||||
{ label: "日期", value: "date" },
|
||||
{ label: "持续时长", value: "duration" },
|
||||
{ label: "循环", value: "cycle" },
|
||||
]
|
||||
// 字段配置
|
||||
export const FIELD_TYPE = [
|
||||
{ label: "字符串", value: "string" },
|
||||
{ label: "表达式", value: "expression" },
|
||||
]
|
||||
export const listenerType = {
|
||||
classListener: "Java 类",
|
||||
expressionListener: "表达式",
|
||||
delegateExpressionListener: "代理表达式",
|
||||
scriptListener: "脚本"
|
||||
};
|
||||
|
||||
export const eventType = {
|
||||
create: "创建",
|
||||
assignment: "指派",
|
||||
complete: "完成",
|
||||
delete: "删除",
|
||||
update: "更新",
|
||||
timeout: "超时"
|
||||
};
|
||||
|
||||
export const fieldType = {
|
||||
string: "字符串",
|
||||
expression: "表达式"
|
||||
};
|
||||
|
|
|
@ -1,331 +1,200 @@
|
|||
<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-form size="small" label-width="90px" @submit.prevent>
|
||||
<el-form-item label="回路特性">
|
||||
<el-select v-model="loopCharacteristics" @change="changeLoopCharacteristicsType">
|
||||
<!--bpmn:MultiInstanceLoopCharacteristics-->
|
||||
<el-option label="并行多重事件" value="ParallelMultiInstance" />
|
||||
<el-option label="时序多重事件" value="SequentialMultiInstance" />
|
||||
<!--bpmn:StandardLoopCharacteristics-->
|
||||
<el-option label="循环事件" value="StandardLoop" />
|
||||
<el-option label="无" value="Null" />
|
||||
</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>
|
||||
<template v-if="loopCharacteristics === 'ParallelMultiInstance' || loopCharacteristics === 'SequentialMultiInstance'">
|
||||
<el-form-item label="循环基数" key="loopCardinality">
|
||||
<el-input v-model="loopInstanceForm.loopCardinality" clearable @change="updateLoopCardinality" />
|
||||
</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 label="集合" key="collection">
|
||||
<el-input v-model="loopInstanceForm.collection" clearable @change="updateLoopBase" />
|
||||
</el-form-item>
|
||||
<el-form-item label="元素变量" key="elementVariable">
|
||||
<el-input v-model="loopInstanceForm.elementVariable" clearable @change="updateLoopBase" />
|
||||
</el-form-item>
|
||||
<el-form-item label="完成条件" key="completionCondition">
|
||||
<el-input v-model="loopInstanceForm.completionCondition" clearable @change="updateLoopCondition" />
|
||||
</el-form-item>
|
||||
<el-form-item label="异步状态" key="async">
|
||||
<el-checkbox v-model="loopInstanceForm.asyncBefore" label="异步前" @change="updateLoopAsync('asyncBefore')" />
|
||||
<el-checkbox v-model="loopInstanceForm.asyncAfter" label="异步后" @change="updateLoopAsync('asyncAfter')" />
|
||||
<el-checkbox
|
||||
v-model="loopInstanceForm.exclusive"
|
||||
v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore"
|
||||
label="排除"
|
||||
@change="updateLoopAsync('exclusive')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="重试周期" prop="timeCycle" v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore" key="timeCycle">
|
||||
<el-input v-model="loopInstanceForm.timeCycle" clearable @change="updateLoopTimeCycle" />
|
||||
</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 }
|
||||
},
|
||||
name: "ElementMultiInstance",
|
||||
props: {
|
||||
id: String,
|
||||
businessObject: Object,
|
||||
type: String
|
||||
},
|
||||
inject: {
|
||||
prefix: "prefix",
|
||||
width: "width"
|
||||
prefix: "prefix"
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
elementListenersList: [], // 监听器列表
|
||||
listenerForm: {}, // 监听器详情表单
|
||||
listenerFormModelVisible: false, // 监听器 编辑 侧边栏显示状态
|
||||
fieldsListOfListener: [],
|
||||
listenerFieldForm: {}, // 监听器 注入字段 详情表单
|
||||
listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
|
||||
editingListenerIndex: -1, // 监听器所在下标,-1 为新增
|
||||
editingListenerFieldIndex: -1, // 字段所在下标,-1 为新增
|
||||
loopCharacteristics: "",
|
||||
//默认配置,用来覆盖原始不存在的选项,避免报错
|
||||
defaultLoopInstanceForm: {
|
||||
completionCondition: "",
|
||||
loopCardinality: "",
|
||||
extensionElements: [],
|
||||
asyncAfter: false,
|
||||
asyncBefore: false,
|
||||
exclusive: false
|
||||
},
|
||||
loopInstanceForm: {}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
id: {
|
||||
businessObject: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
val && val.length && this.$nextTick(() => this.resetListenersList());
|
||||
this.bpmnElement = window.bpmnInstances.bpmnElement;
|
||||
this.getElementLoop(val);
|
||||
}
|
||||
}
|
||||
},
|
||||
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));
|
||||
getElementLoop(businessObject) {
|
||||
if (!businessObject.loopCharacteristics) {
|
||||
this.loopCharacteristics = "Null";
|
||||
this.loopInstanceForm = {};
|
||||
return;
|
||||
}
|
||||
if (businessObject.loopCharacteristics.$type === "bpmn:StandardLoopCharacteristics") {
|
||||
this.loopCharacteristics = "StandardLoop";
|
||||
this.loopInstanceForm = {};
|
||||
return;
|
||||
}
|
||||
if (businessObject.loopCharacteristics.isSequential) {
|
||||
this.loopCharacteristics = "SequentialMultiInstance";
|
||||
} else {
|
||||
this.loopCharacteristics = "ParallelMultiInstance";
|
||||
}
|
||||
// 合并配置
|
||||
this.loopInstanceForm = {
|
||||
...this.defaultLoopInstanceForm,
|
||||
...businessObject.loopCharacteristics,
|
||||
completionCondition: businessObject.loopCharacteristics?.completionCondition?.body ?? "",
|
||||
loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ""
|
||||
};
|
||||
// 保留当前元素 businessObject 上的 loopCharacteristics 实例
|
||||
this.multiLoopInstance = window.bpmnInstances.bpmnElement.businessObject.loopCharacteristics;
|
||||
// 更新表单
|
||||
if (
|
||||
businessObject.loopCharacteristics.extensionElements &&
|
||||
businessObject.loopCharacteristics.extensionElements.values &&
|
||||
businessObject.loopCharacteristics.extensionElements.values.length
|
||||
) {
|
||||
this.loopInstanceForm["timeCycle"] = businessObject.loopCharacteristics.extensionElements.values[0].body
|
||||
}
|
||||
},
|
||||
// 打开 监听器详情 侧边栏
|
||||
openListenerForm(listener, index) {
|
||||
if (listener) {
|
||||
this.listenerForm = initListenerForm(listener);
|
||||
this.editingListenerIndex = index;
|
||||
} else {
|
||||
this.listenerForm = {};
|
||||
this.editingListenerIndex = -1; // 标记为新增
|
||||
changeLoopCharacteristicsType(type) {
|
||||
// this.loopInstanceForm = { ...this.defaultLoopInstanceForm }; // 切换类型取消原表单配置
|
||||
// 取消多实例配置
|
||||
if (type === "Null") {
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { loopCharacteristics: null });
|
||||
return;
|
||||
}
|
||||
if (listener && listener.fields) {
|
||||
this.fieldsListOfListener = listener.fields.map(field => ({
|
||||
...field,
|
||||
fieldType: field.string ? "string" : "expression"
|
||||
}));
|
||||
} else {
|
||||
this.fieldsListOfListener = [];
|
||||
this.listenerForm["fields"] = []
|
||||
// 配置循环
|
||||
if (type === "StandardLoop") {
|
||||
const loopCharacteristicsObject = window.bpmnInstances.moddle.create("bpmn:StandardLoopCharacteristics");
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
|
||||
loopCharacteristics: loopCharacteristicsObject
|
||||
});
|
||||
this.multiLoopInstance = null;
|
||||
return;
|
||||
}
|
||||
// 打开侧边栏并清楚验证状态
|
||||
this.listenerFormModelVisible = true;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs["listenerFormRef"]) this.$refs["listenerFormRef"].clearValidate();
|
||||
// 时序
|
||||
if (type === "SequentialMultiInstance") {
|
||||
this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", {
|
||||
isSequential: true
|
||||
});
|
||||
} else {
|
||||
this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics");
|
||||
}
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
|
||||
loopCharacteristics: this.multiLoopInstance
|
||||
});
|
||||
},
|
||||
// 打开监听器字段编辑弹窗
|
||||
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();
|
||||
// 循环基数
|
||||
updateLoopCardinality(cardinality) {
|
||||
let loopCardinality = null;
|
||||
if (cardinality && cardinality.length) {
|
||||
loopCardinality = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: cardinality });
|
||||
}
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
|
||||
loopCardinality
|
||||
});
|
||||
},
|
||||
// 保存监听器注入字段
|
||||
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);
|
||||
// 完成条件
|
||||
updateLoopCondition(condition) {
|
||||
let completionCondition = null;
|
||||
if (condition && condition.length) {
|
||||
completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: condition });
|
||||
}
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
|
||||
completionCondition
|
||||
});
|
||||
},
|
||||
// 重试周期
|
||||
updateLoopTimeCycle(timeCycle) {
|
||||
const extensionElements = window.bpmnInstances.moddle.create("bpmn:ExtensionElements", {
|
||||
values: [
|
||||
window.bpmnInstances.moddle.create(`${this.prefix}:FailedJobRetryTimeCycle`, {
|
||||
body: timeCycle
|
||||
})
|
||||
]
|
||||
});
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
|
||||
extensionElements
|
||||
});
|
||||
},
|
||||
// 直接更新的基础信息
|
||||
updateLoopBase() {
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
|
||||
collection: this.loopInstanceForm.collection || null,
|
||||
elementVariable: this.loopInstanceForm.elementVariable || null
|
||||
});
|
||||
},
|
||||
// 各异步状态
|
||||
updateLoopAsync(key) {
|
||||
const { asyncBefore, asyncAfter } = this.loopInstanceForm;
|
||||
let asyncAttr = Object.create(null);
|
||||
if (!asyncBefore && !asyncAfter) {
|
||||
this.loopInstanceForm["exclusive"] = false
|
||||
asyncAttr = { asyncBefore: false, asyncAfter: false, exclusive: false, extensionElements: null };
|
||||
} else {
|
||||
this.fieldsListOfListener.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm);
|
||||
this.listenerForm.fields.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm);
|
||||
asyncAttr[key] = this.loopInstanceForm[key];
|
||||
}
|
||||
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 = {};
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, asyncAttr);
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.multiLoopInstance = null;
|
||||
this.bpmnElement = null;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<el-form size="small" label-width="90px" @submit.prevent>
|
||||
<!-- <el-form-item label="异步延续">-->
|
||||
<!-- <el-checkbox v-model="taskConfigForm.asyncBefore" label="异步前" @change="changeTaskAsync" />-->
|
||||
<!-- <el-checkbox v-model="taskConfigForm.asyncAfter" label="异步后" @change="changeTaskAsync" />-->
|
||||
<!-- <el-checkbox v-model="taskConfigForm.exclusive" v-if="taskConfigForm.asyncAfter || taskConfigForm.asyncBefore" label="排除" @change="changeTaskAsync" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="异步延续">
|
||||
<el-checkbox v-model="taskConfigForm.asyncBefore" label="异步前" @change="changeTaskAsync" />
|
||||
<el-checkbox v-model="taskConfigForm.asyncAfter" label="异步后" @change="changeTaskAsync" />
|
||||
<el-checkbox v-model="taskConfigForm.exclusive" v-if="taskConfigForm.asyncAfter || taskConfigForm.asyncBefore" label="排除" @change="changeTaskAsync" />
|
||||
</el-form-item>
|
||||
<component :is="witchTaskComponent" v-bind="$props" />
|
||||
</el-form>
|
||||
</div>
|
||||
|
@ -46,15 +46,15 @@ export default {
|
|||
immediate: true,
|
||||
handler() {
|
||||
this.bpmnElement = window.bpmnInstances.bpmnElement;
|
||||
// this.taskConfigForm.asyncBefore = this.bpmnElement?.businessObject?.asyncBefore;
|
||||
// this.taskConfigForm.asyncAfter = this.bpmnElement?.businessObject?.asyncAfter;
|
||||
// this.taskConfigForm.exclusive = this.bpmnElement?.businessObject?.exclusive;
|
||||
this.taskConfigForm.asyncBefore = this.bpmnElement?.businessObject?.asyncBefore;
|
||||
this.taskConfigForm.asyncAfter = this.bpmnElement?.businessObject?.asyncAfter;
|
||||
this.taskConfigForm.exclusive = this.bpmnElement?.businessObject?.exclusive;
|
||||
}
|
||||
},
|
||||
type: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.witchTaskComponent = this.installedComponent[this.$props.type];
|
||||
this.witchTaskComponent = this.installedComponent[this.type];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,241 +1,51 @@
|
|||
<template>
|
||||
<div style="margin-top: 16px">
|
||||
<el-row>
|
||||
<h4 class="mb-10 fw-700">审批人设置</h4>
|
||||
<el-radio-group v-model="dataType" @change="changeDataType">
|
||||
<el-radio
|
||||
v-for="item in USER_TASK_GROUP"
|
||||
:key="item.value"
|
||||
:label="item.value"
|
||||
>{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" v-if="dataType === USER_TASK_GROUP[0].value">
|
||||
<el-tag v-for="userText in selectedUser.text" :key="userText" effect="plain" closable @close="handleClose(userText)">
|
||||
{{userText}}
|
||||
</el-tag>
|
||||
<div class="element-drawer__button">
|
||||
<el-button size="default" type="primary" :icon="Plus" @click="onSelectUsers()">添加用户</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" v-else-if="dataType === USER_TASK_GROUP[1].value">
|
||||
<el-select v-model="roleIds" multiple size="default" placeholder="请选择角色" @change="changeSelectRoles" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.roleId"
|
||||
:label="item.roleName"
|
||||
:value="`ROLE${item.roleId}`"
|
||||
:disabled="item.status === 1">
|
||||
</el-option>
|
||||
<el-form-item label="处理用户">
|
||||
<el-select v-model="userTaskForm.assignee" @change="updateElementTask('assignee')">
|
||||
<el-option v-for="ak in mockData" :key="'ass-' + ak" :label="`用户${ak}`" :value="`user${ak}`" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="24" v-else-if="dataType === USER_TASK_GROUP[2].value">
|
||||
<TreeSelect
|
||||
size="small"
|
||||
:options="deptTreeData"
|
||||
:objMap="deptProps"
|
||||
multiple
|
||||
clearable
|
||||
checkStrictly
|
||||
nodeKey="id"
|
||||
:selectValue="deptIds"
|
||||
collapseTags
|
||||
@change="checkedDeptChange">
|
||||
</TreeSelect>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" v-show="showMultiFlog">
|
||||
<el-divider />
|
||||
<h4><b>多实例审批方式</b></h4>
|
||||
<el-row>
|
||||
<el-radio-group v-model="multiLoopType" @change="changeMultiLoopType()" class="flex-column radio-group-flex">
|
||||
<el-row v-for="item in MULTI_INSTANCE_TYPE" :key="item.value">
|
||||
<el-radio :label="item.value">{{item.label}}</el-radio>
|
||||
</el-row>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-row v-if="multiLoopType !== MULTI_INSTANCE_TYPE[0].value">
|
||||
<el-tooltip content="开启后,实例需按顺序轮流审批" placement="top-start" @click.stop.prevent>
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
<span class="custom-label">顺序审批:</span>
|
||||
<el-switch v-model="isSequential" @change="changeMultiLoopType()" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="候选用户">
|
||||
<el-select v-model="userTaskForm.candidateUsers" multiple collapse-tags @change="updateElementTask('candidateUsers')">
|
||||
<el-option v-for="uk in mockData" :key="'user-' + uk" :label="`用户${uk}`" :value="`user${uk}`" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="候选分组">
|
||||
<el-select v-model="userTaskForm.candidateGroups" multiple collapse-tags @change="updateElementTask('candidateGroups')">
|
||||
<el-option v-for="gk in mockData" :key="'ass-' + gk" :label="`分组${gk}`" :value="`group${gk}`" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<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>
|
||||
|
||||
<!-- 候选用户弹窗 -->
|
||||
<el-dialog title="候选用户" v-model="userOpen" width="60%" append-to-body>
|
||||
<el-row type="flex" :gutter="20">
|
||||
<!--部门数据-->
|
||||
<el-col :span="7">
|
||||
<el-card shadow="never" style="height: 100%">
|
||||
<div class="head-container">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
placeholder="请输入部门名称"
|
||||
clearable
|
||||
size="small"
|
||||
:prefix-icon="Search"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="deptProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="deptTree"
|
||||
:default-expand-all="false"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
@current-change="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="17">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryForm"
|
||||
size="small"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="用户名称" prop="nickName">
|
||||
<el-input
|
||||
v-model="queryParams.userName"
|
||||
placeholder="请输入用户名称"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Search"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button>
|
||||
<el-button
|
||||
:icon="Refresh"
|
||||
@click="resetQuery"
|
||||
>重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
height="600"
|
||||
v-loading="tableLoading"
|
||||
:data="userTableList"
|
||||
border
|
||||
@row-click="clickRow"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="用户名" align="center" prop="nickName" />
|
||||
<el-table-column label="部门" align="center" prop="dept.deptName" />
|
||||
</el-table>
|
||||
<pagination
|
||||
:total="userTotal"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer class="dialog-footer">
|
||||
<el-button type="primary" size="default" @click="handleTaskUserComplete">确 定</el-button>
|
||||
<el-button size="default" @click="userOpen = false">取 消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { listUser, deptTreeSelect } from "@/api/system/user";
|
||||
import { listRole } from "@/api/system/role";
|
||||
import TreeSelect from "@/components/TreeSelect/index";
|
||||
import { Plus, Search, Refresh } from '@element-plus/icons-vue'
|
||||
import { uniqBy } from 'lodash'
|
||||
|
||||
const USER_TASK_GROUP = [
|
||||
{
|
||||
label: "指定用户",
|
||||
value: "USERS",
|
||||
},
|
||||
{
|
||||
label: "角色",
|
||||
value: "ROLES",
|
||||
},
|
||||
{
|
||||
label: "部门",
|
||||
value: "DEPTS",
|
||||
},
|
||||
{
|
||||
label: "发起人",
|
||||
value: "INITIATOR",
|
||||
},
|
||||
]
|
||||
const USER_TASK_FORM = {
|
||||
dataType: '',
|
||||
assignee: '',
|
||||
candidateUsers: '',
|
||||
candidateGroups: '',
|
||||
text: '',
|
||||
deptId: '',
|
||||
// dueDate: '',
|
||||
// followUpDate: '',
|
||||
// priority: ''
|
||||
}
|
||||
const MULTI_INSTANCE_TYPE = [
|
||||
{ label: "无", value: 'Null' },
|
||||
{ label: "会签(需所有审批人同意)", value: 'SequentialMultiInstance' },
|
||||
{ label: "或签(一名审批人同意即可)", value: 'ParallelMultiInstance' },
|
||||
{ label: "自定义", value: 'DiyMultiInstance' },
|
||||
]
|
||||
export default {
|
||||
name: "UserTask",
|
||||
props: {
|
||||
id: String,
|
||||
type: String
|
||||
},
|
||||
components: { TreeSelect },
|
||||
setup() {
|
||||
return { Plus, Search, Refresh }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableLoading: false,
|
||||
dataType: USER_TASK_GROUP[0].value,
|
||||
selectedUser: {
|
||||
ids: [],
|
||||
text: []
|
||||
defaultTaskForm: {
|
||||
assignee: "",
|
||||
candidateUsers: [],
|
||||
candidateGroups: [],
|
||||
dueDate: "",
|
||||
followUpDate: "",
|
||||
priority: ""
|
||||
},
|
||||
userOpen: false,
|
||||
deptName: undefined,
|
||||
deptOptions: [], //部门列表
|
||||
deptProps: {
|
||||
children: "children",
|
||||
label: "label",
|
||||
value: 'id'
|
||||
},
|
||||
userTableList: [],
|
||||
userTotal: 0,
|
||||
selectedUserDate: [],
|
||||
roleOptions: [],
|
||||
roleIds: [],
|
||||
deptTreeData: [],
|
||||
deptIds: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
deptId: undefined,
|
||||
nickName: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
showMultiFlog: false,
|
||||
isSequential: false,
|
||||
multiLoopType: MULTI_INSTANCE_TYPE[0].value,
|
||||
userTaskForm: {},
|
||||
mockData: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -245,422 +55,32 @@ export default {
|
|||
this.bpmnElement = window.bpmnInstances.bpmnElement;
|
||||
this.$nextTick(() => this.resetTaskForm());
|
||||
}
|
||||
},
|
||||
// 根据名称筛选部门树
|
||||
deptName(val) {
|
||||
this.$refs.deptTree.filter(val);
|
||||
},
|
||||
userTableList: {
|
||||
handler(tableList) {
|
||||
if(tableList.length > 0) {
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if(!!USER_TASK_FORM.assignee) {
|
||||
//单选用户
|
||||
const findObj = tableList.find(item => item.userId === USER_TASK_FORM.assignee)
|
||||
this.selectedUserDate = [findObj]
|
||||
} else if (!!USER_TASK_FORM.candidateUsers) {
|
||||
this.selectedUserDate = USER_TASK_FORM.candidateUsers?.split(',')?.map(Id => {
|
||||
const findObj = tableList.find(item => item.userId === Id)
|
||||
return {...findObj}
|
||||
}) || []
|
||||
}
|
||||
// console.log('this.selectedUserDate', this.selectedUserDate);
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
USER_TASK_GROUP() { return USER_TASK_GROUP },
|
||||
MULTI_INSTANCE_TYPE() { return MULTI_INSTANCE_TYPE }
|
||||
},
|
||||
methods: {
|
||||
// 初始化变量
|
||||
async resetTaskForm() {
|
||||
const bpmnElementObj = this.bpmnElement?.businessObject;
|
||||
if (!bpmnElementObj) {
|
||||
return;
|
||||
}
|
||||
this.clearOptionsData()
|
||||
this.dataType = bpmnElementObj.dataType;
|
||||
if (this.dataType === USER_TASK_GROUP[0].value) {
|
||||
let userIdData = bpmnElementObj['candidateUsers'] || bpmnElementObj['assignee'];
|
||||
let userText = bpmnElementObj.text || [];
|
||||
if (userIdData && userIdData.toString().length > 0 && userText && userText.length > 0) {
|
||||
this.selectedUser.ids = userIdData?.toString().split(',');
|
||||
this.selectedUser.text = userText?.split(',');
|
||||
}
|
||||
if (this.selectedUser.ids.length > 1) {
|
||||
this.showMultiFlog = true;
|
||||
}
|
||||
} else if (this.dataType === USER_TASK_GROUP[1].value) {
|
||||
// 获取角色列表
|
||||
this.getRoleOptions();
|
||||
let roleIdData = bpmnElementObj['candidateGroups'] || [];
|
||||
if (roleIdData && roleIdData.length > 0) {
|
||||
this.roleIds = roleIdData.split(',')
|
||||
}
|
||||
this.showMultiFlog = true;
|
||||
} else if (this.dataType === USER_TASK_GROUP[2].value) {
|
||||
// 获取部门列表
|
||||
await this.getDeptTreeData();
|
||||
let deptIdData = bpmnElementObj['candidateGroups'] || [];
|
||||
if (deptIdData && deptIdData.length > 0) {
|
||||
this.deptIds = deptIdData.split(',');
|
||||
// 回显
|
||||
this.checkedDeptChange(this.deptIds);
|
||||
}
|
||||
this.showMultiFlog = true;
|
||||
}
|
||||
this.getElementLoop(bpmnElementObj);
|
||||
},
|
||||
// 清空选项数据
|
||||
clearOptionsData() {
|
||||
this.selectedUser.ids = [];
|
||||
this.selectedUser.text = [];
|
||||
this.roleIds = [];
|
||||
this.deptIds = [];
|
||||
},
|
||||
// 更新节点数据
|
||||
updateElementTask() {
|
||||
const taskObj = Object.assign({}, { ...USER_TASK_FORM })
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskObj);
|
||||
// console.log('updateElementTask', this.bpmnElement?.businessObject);
|
||||
},
|
||||
// 查询部门下拉树结构
|
||||
getDeptOptions() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.deptOptions || this.deptOptions.length <= 0) {
|
||||
// 选择部门树 数据第一次请求
|
||||
deptTreeSelect().then(response => {
|
||||
this.deptOptions = [].concat(
|
||||
[{ id: '', label: '全部', children: [] }],
|
||||
[...response.data]
|
||||
);
|
||||
this.handleNodeClick(this.deptOptions[0])
|
||||
resolve()
|
||||
})
|
||||
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 {
|
||||
// 确保选择部门树已初始化 但仍请求表格数据 复选框回显
|
||||
this.handleNodeClick(this.deptOptions[0])
|
||||
value = this.bpmnElement?.businessObject[key] || this.defaultTaskForm[key];
|
||||
}
|
||||
this.userTaskForm[key] = value
|
||||
}
|
||||
});
|
||||
},
|
||||
// 查询部门下拉树结构(含部门前缀)
|
||||
getDeptTreeData() {
|
||||
function refactorTree(data) {
|
||||
return data.map(node => {
|
||||
let treeData = { id: `DEPT${node.id}`, label: node.label, parentId: node.parentId, weight: node.weight };
|
||||
if (node.children && node.children.length > 0) {
|
||||
treeData.children = refactorTree(node.children);
|
||||
}
|
||||
return treeData;
|
||||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.deptTreeData || this.deptTreeData.length <= 0) {
|
||||
deptTreeSelect().then((res) => {
|
||||
this.deptTreeData = refactorTree(res.data);
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
reject()
|
||||
})
|
||||
updateElementTask(key) {
|
||||
const taskAttr = Object.create(null);
|
||||
if (key === "candidateUsers" || key === "candidateGroups") {
|
||||
taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key].join() : null;
|
||||
} else {
|
||||
resolve()
|
||||
taskAttr[key] = this.userTaskForm[key] || null;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查询部门下拉树结构
|
||||
getRoleOptions() {
|
||||
if (!this.roleOptions || this.roleOptions.length <= 0) {
|
||||
listRole().then(response => this.roleOptions = response.rows);
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
|
||||
}
|
||||
},
|
||||
// 查询用户列表
|
||||
getList() {
|
||||
this.tableLoading = true
|
||||
listUser({ ...this.queryParams }).then(response => {
|
||||
this.userTableList = response.rows;
|
||||
this.userTotal = response.total;
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.selectedUserDate?.forEach(each => {
|
||||
const findObj = this.userTableList.find(find => find.userId === each.userId) || {}
|
||||
if(Object.keys(findObj).length > 0) {
|
||||
this.$refs.multipleTable.toggleRowSelection(findObj)
|
||||
}
|
||||
})
|
||||
}, 500)
|
||||
})
|
||||
}).finally(() => {
|
||||
this.tableLoading = false
|
||||
})
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.$refs.queryForm.resetFields();
|
||||
this.$refs.queryForm.clearValidate();
|
||||
this.queryParams = {
|
||||
deptId: '',
|
||||
nickName: undefined,
|
||||
pageSize: 20
|
||||
};
|
||||
this.handleQuery();
|
||||
},
|
||||
// 筛选节点
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
// 节点单击事件
|
||||
handleNodeClick(data) {
|
||||
this.queryParams.deptId = data.id;
|
||||
this.handleQuery();
|
||||
},
|
||||
// 关闭标签
|
||||
handleClose(tag) {
|
||||
this.selectedUserDate.splice(this.selectedUserDate.indexOf(tag), 1);
|
||||
this.handleTaskUserChange()
|
||||
},
|
||||
/**
|
||||
* 选择行
|
||||
*/
|
||||
clickRow(row) {
|
||||
this.$refs.multipleTable.toggleRowSelection(row);
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
if(selection.length) {
|
||||
const concatData = [].concat(selection, this.selectedUserDate);
|
||||
this.selectedUserDate = uniqBy(concatData, 'userId');
|
||||
}
|
||||
},
|
||||
// 添加用户
|
||||
onSelectUsers() {
|
||||
this.$refs.multipleTable?.clearSelection();
|
||||
this.getDeptOptions()
|
||||
this.userOpen = true;
|
||||
},
|
||||
// 添加用户-确认按钮
|
||||
handleTaskUserComplete() {
|
||||
if (!this.selectedUserDate || this.selectedUserDate.length <= 0) {
|
||||
this.$modal.msgError('请选择用户');
|
||||
return;
|
||||
}
|
||||
USER_TASK_FORM.dataType = USER_TASK_GROUP[0].value;
|
||||
USER_TASK_FORM.deptId = this.queryParams.deptId;
|
||||
this.handleTaskUserChange()
|
||||
this.changeMultiLoopType();
|
||||
this.userOpen = false;
|
||||
},
|
||||
// 指定用户改变确定
|
||||
handleTaskUserChange() {
|
||||
this.selectedUser.text = this.selectedUserDate.map(item => item.nickName) || [];
|
||||
if (this.selectedUserDate.length === 1) {
|
||||
let data = this.selectedUserDate[0];
|
||||
USER_TASK_FORM.assignee = data.userId;
|
||||
USER_TASK_FORM.text = data.nickName;
|
||||
USER_TASK_FORM.candidateUsers = null;
|
||||
this.showMultiFlog = false;
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[0].value;
|
||||
} else {
|
||||
USER_TASK_FORM.candidateUsers = this.selectedUserDate.map(item => item.userId).join() || null;
|
||||
USER_TASK_FORM.text = this.selectedUserDate.map(item => item.nickName).join() || null;
|
||||
USER_TASK_FORM.assignee = null;
|
||||
this.showMultiFlog = true;
|
||||
}
|
||||
this.updateElementTask();
|
||||
},
|
||||
// 选中角色
|
||||
changeSelectRoles(roleArray) {
|
||||
let groups = null;
|
||||
let text = null;
|
||||
if (roleArray && roleArray.length > 0) {
|
||||
USER_TASK_FORM.dataType = USER_TASK_GROUP[1].value;
|
||||
groups = roleArray.join() || null;
|
||||
let textArr = this.roleOptions.filter(k => roleArray.indexOf(`ROLE${k.roleId}`) >= 0);
|
||||
text = textArr?.map(k => k.roleName).join() || null;
|
||||
} else {
|
||||
USER_TASK_FORM.dataType = null;
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[0].value;
|
||||
}
|
||||
USER_TASK_FORM.candidateGroups = groups;
|
||||
USER_TASK_FORM.text = text;
|
||||
this.updateElementTask();
|
||||
this.changeMultiLoopType();
|
||||
},
|
||||
// 选中部门
|
||||
checkedDeptChange(deptArray) {
|
||||
let groups = null;
|
||||
let text = null;
|
||||
this.deptIds = deptArray;
|
||||
if (deptArray && deptArray.length > 0) {
|
||||
USER_TASK_FORM.dataType = USER_TASK_GROUP[2].value;
|
||||
groups = deptArray.join(',') || null;
|
||||
let treeStarkData = JSON.parse(JSON.stringify(this.deptTreeData));
|
||||
const filterData = treeStarkData?.filter(item => {
|
||||
return deptArray.includes(item.id)
|
||||
})
|
||||
text = filterData?.map(item => item.label).join(',') || null
|
||||
} else {
|
||||
USER_TASK_FORM.dataType = null;
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[0].value;
|
||||
}
|
||||
USER_TASK_FORM.candidateGroups = groups;
|
||||
USER_TASK_FORM.text = text;
|
||||
this.updateElementTask();
|
||||
this.changeMultiLoopType();
|
||||
},
|
||||
// 修改审批人类型
|
||||
changeDataType(val) {
|
||||
if (val === USER_TASK_GROUP[1].value || val === USER_TASK_GROUP[2].value || (val === USER_TASK_GROUP[0].value && this.selectedUser.ids.length > 1)) {
|
||||
this.showMultiFlog = true;
|
||||
} else {
|
||||
this.showMultiFlog = false;
|
||||
}
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[0].value;
|
||||
this.changeMultiLoopType();
|
||||
// 清空 USER_TASK_FORM 所有属性值
|
||||
Object.keys(USER_TASK_FORM).forEach(key => USER_TASK_FORM[key] = null);
|
||||
USER_TASK_FORM.dataType = val;
|
||||
if (val === USER_TASK_GROUP[0].value) {
|
||||
if (this.selectedUser && this.selectedUser.ids && this.selectedUser.ids.length > 0) {
|
||||
if (this.selectedUser.ids.length === 1) {
|
||||
USER_TASK_FORM.assignee = this.selectedUser.ids[0];
|
||||
} else {
|
||||
USER_TASK_FORM.candidateUsers = this.selectedUser.ids.join()
|
||||
}
|
||||
USER_TASK_FORM.text = this.selectedUser.text?.join() || null
|
||||
}
|
||||
} else if (val === USER_TASK_GROUP[1].value) {
|
||||
this.getRoleOptions();
|
||||
if (this.roleIds && this.roleIds.length > 0) {
|
||||
USER_TASK_FORM.candidateGroups = this.roleIds.join() || null;
|
||||
let textArr = this.roleOptions.filter(k => this.roleIds.indexOf(`ROLE${k.roleId}`) >= 0);
|
||||
USER_TASK_FORM.text = textArr?.map(k => k.roleName).join() || null;
|
||||
}
|
||||
} else if (val === USER_TASK_GROUP[2].value) {
|
||||
this.getDeptTreeData();
|
||||
if (this.deptIds && this.deptIds.length > 0) {
|
||||
USER_TASK_FORM.candidateGroups = this.deptIds.join() || null;
|
||||
let textArr = []
|
||||
let treeStarkData = JSON.parse(JSON.stringify(this.deptTreeData));
|
||||
this.deptIds.forEach(id => {
|
||||
let stark = []
|
||||
stark = stark.concat(treeStarkData);
|
||||
while(stark.length) {
|
||||
let temp = stark.shift();
|
||||
if(temp.children) {
|
||||
stark = temp.children.concat(stark);
|
||||
}
|
||||
if(id === temp.id) {
|
||||
textArr.push(temp);
|
||||
}
|
||||
}
|
||||
})
|
||||
USER_TASK_FORM.text = textArr?.map(k => k.label).join() || null;
|
||||
}
|
||||
} else {
|
||||
USER_TASK_FORM.assignee = "${initiator}";
|
||||
USER_TASK_FORM.text = "流程发起人";
|
||||
}
|
||||
this.updateElementTask();
|
||||
},
|
||||
// 初始化多实例变量
|
||||
getElementLoop(businessObject) {
|
||||
if (!businessObject.loopCharacteristics) {
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[0].value;
|
||||
return;
|
||||
}
|
||||
this.isSequential = businessObject.loopCharacteristics.isSequential;
|
||||
if (businessObject.loopCharacteristics.completionCondition) {
|
||||
if (businessObject.loopCharacteristics.completionCondition.body === "${nrOfCompletedInstances >= nrOfInstances}") {
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[1].value; // 会签
|
||||
} else if (businessObject.loopCharacteristics.completionCondition.body === "${nrOfCompletedInstances >= 0}") {
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[2].value; // 或签
|
||||
} else {
|
||||
this.multiLoopType = MULTI_INSTANCE_TYPE[3].value; // 自定义
|
||||
}
|
||||
}
|
||||
},
|
||||
// 更新多实例变量
|
||||
changeMultiLoopType() {
|
||||
// 取消多实例配置
|
||||
if (this.multiLoopType === MULTI_INSTANCE_TYPE[0].value) {
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { loopCharacteristics: null, assignee: null });
|
||||
return;
|
||||
}
|
||||
this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { isSequential: this.isSequential });
|
||||
// 更新多实例配置
|
||||
window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
|
||||
loopCharacteristics: this.multiLoopInstance,
|
||||
assignee: '${assignee}'
|
||||
});
|
||||
// 设置审批人
|
||||
USER_TASK_FORM.assignee = '${assignee}';
|
||||
// 完成条件
|
||||
let completionCondition = null;
|
||||
switch (this.multiLoopType) {
|
||||
case MULTI_INSTANCE_TYPE[1].value:
|
||||
completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: "${nrOfCompletedInstances >= nrOfInstances}" });
|
||||
break;
|
||||
case MULTI_INSTANCE_TYPE[2].value:
|
||||
completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: "${nrOfCompletedInstances > 0}" });
|
||||
break;
|
||||
default:
|
||||
completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: "" });
|
||||
break;
|
||||
}
|
||||
// 更新模块属性信息
|
||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
|
||||
collection: MULTI_INSTANCE_TYPE[1].value || MULTI_INSTANCE_TYPE[2].value ? '${multiInstanceHandler.getUserIds(execution)}' : "",
|
||||
elementVariable: MULTI_INSTANCE_TYPE[1].value || MULTI_INSTANCE_TYPE[2].value ? 'assignee' : "",
|
||||
completionCondition
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
this.bpmnElement = null;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.el-row .el-radio-group {
|
||||
margin-bottom: 15px;
|
||||
.el-radio {
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
.el-tag {
|
||||
margin-bottom: 10px;
|
||||
+ .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-label {
|
||||
padding-left: 5px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.head-container {
|
||||
height: 480px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.el-row .radio-group-flex {
|
||||
margin: 15px 0 0 0;
|
||||
justify-items: flex-start;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -68,28 +68,6 @@
|
|||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.listener-drawer {
|
||||
|
||||
.el-drawer__header {
|
||||
margin: 0PX;
|
||||
padding: 10PX;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
.el-drawer__title {
|
||||
font-size: 18px
|
||||
}
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
.el-form-item__label {
|
||||
font-size: 14PX;
|
||||
font-weight: 500;
|
||||
}
|
||||
.input-with-select .el-input-group__prepend {
|
||||
background-color: var(--el-fill-color-blank);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.listener-filed__title {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
|
|
Loading…
Reference in New Issue