add 流程设计面板
This commit is contained in:
parent
2c60905db2
commit
aba0040f14
@ -3,12 +3,12 @@
|
|||||||
<div v-if="nodeName">{{ nodeName }}</div>
|
<div v-if="nodeName">{{ nodeName }}</div>
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<component :is="component" v-if="element" :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys" />
|
<component :is="component" v-if="element" :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys" />
|
||||||
<!-- <TaskPanel :element="element" :modeler="modeler" :users="users" :groups="groups" :categorys="categorys"></TaskPanel>-->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="PropertyPanel">
|
<script setup lang="ts" name="PropertyPanel">
|
||||||
import { NodeName } from './assets/lang/zh';
|
import { NodeName } from './assets/lang/zh';
|
||||||
import TaskPanel from './panel/TaskPanel.vue';
|
import TaskPanel from './panel/TaskPanel.vue';
|
||||||
|
import ProcessPanel from './panel/ProcessPanel.vue';
|
||||||
interface propsType {
|
interface propsType {
|
||||||
users: Array<any>;
|
users: Array<any>;
|
||||||
groups: Array<any>;
|
groups: Array<any>;
|
||||||
@ -53,7 +53,7 @@ const component = computed(() => {
|
|||||||
if (taskType.includes(type)) return TaskPanel;
|
if (taskType.includes(type)) return TaskPanel;
|
||||||
if (sequenceType.includes(type)) return 'sequenceFlowPanel';
|
if (sequenceType.includes(type)) return 'sequenceFlowPanel';
|
||||||
if (gatewayType.includes(type)) return 'gatewayPanel';
|
if (gatewayType.includes(type)) return 'gatewayPanel';
|
||||||
if (processType.includes(type)) return 'processPanel';
|
if (processType.includes(type)) return ProcessPanel;
|
||||||
return console.error('no ' + type + ' type panel');
|
return console.error('no ' + type + ' type panel');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,4 +5,6 @@ import EnhancementContextPad from './ContextPad';
|
|||||||
// 翻译模块
|
// 翻译模块
|
||||||
import TranslationModule from './Translate';
|
import TranslationModule from './Translate';
|
||||||
|
|
||||||
export default [EnhancementPaletteProvider, EnhancementContextPad, TranslationModule];
|
import { ModuleDeclaration } from 'didi';
|
||||||
|
const Module: ModuleDeclaration[] = [EnhancementPaletteProvider, EnhancementContextPad, TranslationModule];
|
||||||
|
export default Module;
|
||||||
|
30
src/components/BpmnDesign/hooks/usePanel.ts
Normal file
30
src/components/BpmnDesign/hooks/usePanel.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Ref } from 'vue';
|
||||||
|
import showConfig from '@/components/BpmnDesign/assets/showConfig';
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
modeler: any;
|
||||||
|
element: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (ops: Options) => {
|
||||||
|
const { modeler, element } = ops;
|
||||||
|
|
||||||
|
const elementType = computed(() => {
|
||||||
|
const bizObj = element.businessObject;
|
||||||
|
return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type;
|
||||||
|
});
|
||||||
|
|
||||||
|
const config = computed(() => showConfig[elementType.value] || {});
|
||||||
|
|
||||||
|
const updateProperties = (properties: any) => {
|
||||||
|
const modeling = modeler.get('modeling');
|
||||||
|
modeling.updateProperties(element, properties);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
elementType,
|
||||||
|
showConfig: config,
|
||||||
|
|
||||||
|
updateProperties
|
||||||
|
};
|
||||||
|
};
|
@ -98,8 +98,8 @@ const groups = [
|
|||||||
{ name: 'python组', id: 'python' }
|
{ name: 'python组', id: 'python' }
|
||||||
];
|
];
|
||||||
const categorys = [
|
const categorys = [
|
||||||
{ name: 'OA', id: 'oa' },
|
{ label: 'OA', id: 'oa', value: 'id' },
|
||||||
{ name: '财务', id: 'finance' }
|
{ label: '财务', id: 'finance', value: 'finance' }
|
||||||
];
|
];
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
53
src/components/BpmnDesign/panel/ProcessPanel.vue
Normal file
53
src/components/BpmnDesign/panel/ProcessPanel.vue
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
|
||||||
|
<el-form-item label="流程分类" prop="processCategory">
|
||||||
|
<el-select v-model="formData.processCategory">
|
||||||
|
<el-option v-for="item in categorys" :key="item.id" :label="item.label" :value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="流程标识" prop="id">
|
||||||
|
<el-input v-model="formData.id"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="流程名称" prop="name">
|
||||||
|
<el-input v-model="formData.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="节点描述" prop="description">
|
||||||
|
<el-input v-model="formData.description"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="执行监听器" style="margin-bottom: 0"> </el-form-item>
|
||||||
|
<ExecutionListener :modeler="modeler" :element="element"></ExecutionListener>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="ProcessPanel">
|
||||||
|
import ExecutionListener from './property/ExecutionListener.vue';
|
||||||
|
import { ProcessPanel } from 'bpmnDesign';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
interface PropType {
|
||||||
|
modeler: any;
|
||||||
|
element: any;
|
||||||
|
categorys?: any[];
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<PropType>(), {
|
||||||
|
categorys: () => []
|
||||||
|
});
|
||||||
|
|
||||||
|
const formData = ref<ProcessPanel>({
|
||||||
|
processCategory: '',
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
description: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRules = ref<ElFormRules>({
|
||||||
|
processCategory: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
|
id: [{ required: true, message: '请输入', trigger: 'blur' }],
|
||||||
|
name: [{ required: true, message: '请输入', trigger: 'blur' }]
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
@ -1,9 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-form ref="formRef">
|
<el-form ref="formRef" v-model="formData" label-width="80px">
|
||||||
|
<el-form-item prop="id" label="节点 id">
|
||||||
|
<el-input v-model="formData.id" placeholder="请输入"> </el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="任务监听器">
|
<el-form-item label="任务监听器">
|
||||||
<el-badge :value="taskListenerCount">
|
<el-badge :value="taskListenerCount">
|
||||||
<el-button @click="taskListenerRef.open()">编辑</el-button>
|
<el-button @click="taskListenerRef.openDialog()">编辑</el-button>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -31,6 +34,7 @@ const elementType = computed(() => {
|
|||||||
const config = computed(() => showConfig[elementType.value] || {});
|
const config = computed(() => showConfig[elementType.value] || {});
|
||||||
const taskListenerRef = ref<InstanceType<typeof TaskListener>>();
|
const taskListenerRef = ref<InstanceType<typeof TaskListener>>();
|
||||||
const taskListenerCount = ref(0);
|
const taskListenerCount = ref(0);
|
||||||
|
const formData = ref({});
|
||||||
|
|
||||||
const refreshTaskListener = (count?: number) => {
|
const refreshTaskListener = (count?: number) => {
|
||||||
if (count) {
|
if (count) {
|
||||||
@ -40,11 +44,6 @@ const refreshTaskListener = (count?: number) => {
|
|||||||
props.element.businessObject.extensionElements?.values?.filter((item) => item.$type === 'flowable:TaskListener').length ?? 0;
|
props.element.businessObject.extensionElements?.values?.filter((item) => item.$type === 'flowable:TaskListener').length ?? 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProperties = (properties: any) => {
|
|
||||||
const modeling = props.modeler.get('modeling');
|
|
||||||
modeling.updateProperties(props.element, properties);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
269
src/components/BpmnDesign/panel/property/ExecutionListener.vue
Normal file
269
src/components/BpmnDesign/panel/property/ExecutionListener.vue
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<vxe-toolbar>
|
||||||
|
<template #buttons>
|
||||||
|
<el-button type="primary" link size="small" @click="insertEvent">新增</el-button>
|
||||||
|
<el-button type="primary" link size="small" @click="removeSelectRowEvent">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</vxe-toolbar>
|
||||||
|
<vxe-table
|
||||||
|
ref="tableRef"
|
||||||
|
size="mini"
|
||||||
|
height="100px"
|
||||||
|
border
|
||||||
|
show-overflow
|
||||||
|
keep-source
|
||||||
|
:data="tableData"
|
||||||
|
:menu-config="menuConfig"
|
||||||
|
:edit-rules="tableRules"
|
||||||
|
:edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
|
||||||
|
@cell-dblclick="cellDBLClickEvent"
|
||||||
|
@menu-click="contextMenuClickEvent"
|
||||||
|
>
|
||||||
|
<vxe-column type="checkbox" width="40"></vxe-column>
|
||||||
|
<vxe-column type="seq" width="40"></vxe-column>
|
||||||
|
<vxe-column field="event" title="事件" min-width="100px">
|
||||||
|
<template #default="slotParams">
|
||||||
|
<span>{{ eventSelect.find((e) => e.value === slotParams.row.event)?.label }}</span>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="type" title="类型" min-width="100px">
|
||||||
|
<template #default="slotParams">
|
||||||
|
<span>{{ typeSelect.find((e) => e.value === slotParams.row.type)?.label }}</span>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="className" title="Java 类名" min-width="100px"> </vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="formDialog.visible.value"
|
||||||
|
:title="formDialog.title.value"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
:show-close="false"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="tableRules" label-width="90px">
|
||||||
|
<el-form-item label="事件" prop="event">
|
||||||
|
<el-select v-model="formData.event">
|
||||||
|
<el-option v-for="item in eventSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="类型" prop="type">
|
||||||
|
<el-select v-model="formData.type">
|
||||||
|
<el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Java 类名" prop="className">
|
||||||
|
<el-input v-model="formData.className" type="text"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="参数">
|
||||||
|
<ListenerParam ref="listenerParamRef" :table-data="formData.params" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="formDialog.closeDialog">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="submitEvent">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import ListenerParam from './ListenerParam.vue';
|
||||||
|
import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
|
||||||
|
import { ExecutionListenerVO } from 'bpmnDesign';
|
||||||
|
import usePanel from '@/components/BpmnDesign/hooks/usePanel';
|
||||||
|
import useDialog from '@/hooks/useDialog';
|
||||||
|
|
||||||
|
const emit = defineEmits(['close']);
|
||||||
|
interface PropType {
|
||||||
|
modeler: any;
|
||||||
|
element: any;
|
||||||
|
categorys?: any[];
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<PropType>(), {
|
||||||
|
categorys: () => []
|
||||||
|
});
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
const initData: ExecutionListenerVO = {
|
||||||
|
event: '',
|
||||||
|
type: '',
|
||||||
|
className: '',
|
||||||
|
params: []
|
||||||
|
};
|
||||||
|
const formData = reactive<ExecutionListenerVO>(initData);
|
||||||
|
|
||||||
|
const selectRow = ref<ExecutionListenerVO | null>();
|
||||||
|
const formDialog = useDialog({
|
||||||
|
title: selectRow.value ? '编辑&保存' : '新增&保存'
|
||||||
|
});
|
||||||
|
|
||||||
|
const { title, visible, openDialog, closeDialog } = useDialog({
|
||||||
|
title: '执行监听器'
|
||||||
|
});
|
||||||
|
const { showConfig, elementType, updateProperties } = usePanel({
|
||||||
|
modeler: props.modeler,
|
||||||
|
element: toRaw(props.element)
|
||||||
|
});
|
||||||
|
|
||||||
|
const listenerParamRef = ref<InstanceType<typeof ListenerParam>>();
|
||||||
|
const tableRef = ref<VxeTableInstance<ExecutionListenerVO>>();
|
||||||
|
const formRef = ref<ElFormInstance>();
|
||||||
|
const currentIndex = ref(0);
|
||||||
|
const tableData = ref<ExecutionListenerVO[]>([]);
|
||||||
|
const tableRules = ref<ElFormRules>({
|
||||||
|
event: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
|
type: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
|
className: [{ required: true, message: '请输入', trigger: 'blur' }]
|
||||||
|
});
|
||||||
|
|
||||||
|
const submitEvent = async () => {
|
||||||
|
const error = await listenerParamRef.value.validate();
|
||||||
|
await formRef.value.validate((validate) => {
|
||||||
|
if (validate && !error) {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
if ($table) {
|
||||||
|
formData.params = listenerParamRef.value.getTableData();
|
||||||
|
if (selectRow.value) {
|
||||||
|
Object.assign(selectRow.value, formData);
|
||||||
|
} else {
|
||||||
|
$table.insertAt({ ...formData }, -1);
|
||||||
|
}
|
||||||
|
updateElement();
|
||||||
|
formDialog.closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSelectRowEvent = async () => {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
if ($table) {
|
||||||
|
const selectCount = $table.getCheckboxRecords().length;
|
||||||
|
if (selectCount === 0) {
|
||||||
|
proxy?.$modal.msgWarning('请选择行');
|
||||||
|
} else {
|
||||||
|
await $table.removeCheckboxRow();
|
||||||
|
updateElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const insertEvent = async () => {
|
||||||
|
Object.assign(formData, initData);
|
||||||
|
selectRow.value = null;
|
||||||
|
formDialog.openDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
const editEvent = (row: ExecutionListenerVO) => {
|
||||||
|
Object.assign(formData, row);
|
||||||
|
selectRow.value = row;
|
||||||
|
formDialog.openDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeEvent = async (row: ExecutionListenerVO) => {
|
||||||
|
await proxy?.$modal.confirm('您确定要删除该数据?');
|
||||||
|
const $table = tableRef.value;
|
||||||
|
if ($table) {
|
||||||
|
await $table.remove(row);
|
||||||
|
updateElement();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const updateElement = () => {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
const data = $table.getTableData().fullData;
|
||||||
|
if (data.length) {
|
||||||
|
let extensionElements = props.element.businessObject.get('extensionElements');
|
||||||
|
if (!extensionElements) {
|
||||||
|
extensionElements = props.modeler.get('moddle').create('bpmn:ExtensionElements');
|
||||||
|
}
|
||||||
|
// 清除旧值
|
||||||
|
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
|
||||||
|
data.forEach((item) => {
|
||||||
|
const executionListener = props.modeler.get('moddle').create('flowable:ExecutionListener');
|
||||||
|
executionListener['event'] = item.event;
|
||||||
|
executionListener[item.type] = item.className;
|
||||||
|
if (item.params && item.params.length) {
|
||||||
|
item.params.forEach((field) => {
|
||||||
|
const fieldElement = props.modeler.get('moddle').create('flowable:Field');
|
||||||
|
fieldElement['name'] = field.name;
|
||||||
|
fieldElement[field.type] = field.value;
|
||||||
|
executionListener.get('fields').push(fieldElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
extensionElements.get('values').push(executionListener);
|
||||||
|
});
|
||||||
|
updateProperties({ extensionElements: extensionElements });
|
||||||
|
} else {
|
||||||
|
const extensionElements = props.element.businessObject[`extensionElements`];
|
||||||
|
if (extensionElements) {
|
||||||
|
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openDialog
|
||||||
|
});
|
||||||
|
|
||||||
|
const cellDBLClickEvent: VxeTableEvents.CellDblclick<ExecutionListenerVO> = ({ row }) => {
|
||||||
|
editEvent(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
const menuConfig = reactive<VxeTablePropTypes.MenuConfig<ExecutionListenerVO>>({
|
||||||
|
body: {
|
||||||
|
options: [
|
||||||
|
[
|
||||||
|
{ code: 'edit', name: '编辑', prefixIcon: 'vxe-icon-edit', disabled: false },
|
||||||
|
{ code: 'remove', name: '删除', prefixIcon: 'vxe-icon-delete', disabled: false }
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
visibleMethod({ options, column }) {
|
||||||
|
const isDisabled = !column;
|
||||||
|
options.forEach((list) => {
|
||||||
|
list.forEach((item) => {
|
||||||
|
item.disabled = isDisabled;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const contextMenuClickEvent: VxeTableEvents.MenuClick<ExecutionListenerVO> = ({ menu, row, column }) => {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
if ($table) {
|
||||||
|
switch (menu.code) {
|
||||||
|
case 'edit':
|
||||||
|
editEvent(row);
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
removeEvent(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const typeSelect = [
|
||||||
|
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' },
|
||||||
|
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' },
|
||||||
|
{ id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' }
|
||||||
|
];
|
||||||
|
const eventSelect = [
|
||||||
|
{ id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: 'start', value: 'start' },
|
||||||
|
{ id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: 'end', value: 'end' },
|
||||||
|
{ id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: 'take', value: 'take' }
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.el-badge {
|
||||||
|
:deep(.el-badge__content) {
|
||||||
|
top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,13 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
|
||||||
:model-value="visible"
|
|
||||||
title="监听器参数"
|
|
||||||
width="700px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:close-on-press-escape="false"
|
|
||||||
:show-close="false"
|
|
||||||
append-to-body
|
|
||||||
>
|
|
||||||
<vxe-toolbar>
|
<vxe-toolbar>
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<el-button icon="Plus" @click="insertRow">新增</el-button>
|
<el-button icon="Plus" @click="insertRow">新增</el-button>
|
||||||
@ -15,7 +6,7 @@
|
|||||||
</vxe-toolbar>
|
</vxe-toolbar>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
height="300px"
|
:height="height"
|
||||||
border
|
border
|
||||||
show-overflow
|
show-overflow
|
||||||
keep-source
|
keep-source
|
||||||
@ -52,56 +43,47 @@
|
|||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="ListenerParam">
|
<script setup lang="ts" name="ListenerParam">
|
||||||
import { VXETable, VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
|
import { VXETable, VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
|
||||||
import { ParamVO } from 'bpmnDesign';
|
import { ParamVO } from 'bpmnDesign';
|
||||||
|
import useDialog from '@/hooks/useDialog';
|
||||||
|
|
||||||
interface PropType {
|
interface PropType {
|
||||||
modelValue: ParamVO[];
|
height?: string;
|
||||||
visible?: boolean;
|
tableData?: ParamVO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
const props = withDefaults(defineProps<PropType>(), {
|
const props = withDefaults(defineProps<PropType>(), {
|
||||||
visible: false
|
height: '200px',
|
||||||
|
tableData: () => []
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableData = computed(() => props.modelValue);
|
|
||||||
|
|
||||||
const tableRules = ref<VxeTablePropTypes.EditRules>({
|
const tableRules = ref<VxeTablePropTypes.EditRules>({
|
||||||
type: [{ required: true, message: '请选择', trigger: 'blur' }],
|
type: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '请输入', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入', trigger: 'blur' }],
|
||||||
value: [{ required: true, message: '请输入', trigger: 'blur' }]
|
value: [{ required: true, message: '请输入', trigger: 'blur' }]
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(['update:modelValue', 'update:visible']);
|
const { title, visible, openDialog, closeDialog } = useDialog({
|
||||||
|
title: '监听器参数'
|
||||||
|
});
|
||||||
const typeSelect = [
|
const typeSelect = [
|
||||||
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '字符串', value: 'stringValue' },
|
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '字符串', value: 'stringValue' },
|
||||||
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' }
|
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const tableRef = ref<VxeTableInstance<ParamVO>>();
|
const tableRef = ref<VxeTableInstance<ParamVO>>();
|
||||||
const submitForm = async () => {
|
|
||||||
|
const getTableData = () => {
|
||||||
const $table = tableRef.value;
|
const $table = tableRef.value;
|
||||||
if ($table) {
|
if ($table) {
|
||||||
const errMap = await $table.validate(true);
|
return $table.getTableData().fullData;
|
||||||
if (errMap) {
|
|
||||||
proxy?.$modal.msgError('校验不通过');
|
|
||||||
} else {
|
|
||||||
emits('update:modelValue', $table.getTableData().fullData);
|
|
||||||
emits('update:visible', false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertRow = async () => {
|
const insertRow = async () => {
|
||||||
@ -120,6 +102,20 @@ const removeRow = async (row: ParamVO) => {
|
|||||||
await $table.remove(row);
|
await $table.remove(row);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const validate = async () => {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
if ($table) {
|
||||||
|
return await $table.validate(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
closeDialog,
|
||||||
|
openDialog,
|
||||||
|
validate,
|
||||||
|
getTableData
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:model-value="visible"
|
v-model="visible"
|
||||||
title="任务监听器"
|
:title="title"
|
||||||
width="900px"
|
width="900px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:close-on-press-escape="false"
|
:close-on-press-escape="false"
|
||||||
@ -66,20 +66,31 @@
|
|||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" size="small" @click="submitForm">确 定</el-button>
|
<el-button @click="closeDialog">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<ListenerParam v-if="showParamDialog" v-model:visible="showParamDialog" v-model="tableData[currentIndex].params" />
|
|
||||||
|
<ListenerParam
|
||||||
|
ref="listenerParamRef"
|
||||||
|
@update-data="
|
||||||
|
(data: ParamVO[]) => {
|
||||||
|
tableData[currentIndex].params = data;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ListenerParam from './ListenerParam.vue';
|
import ListenerParam from './ListenerParam.vue';
|
||||||
import showConfig from '../../assets/showConfig';
|
|
||||||
import { VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
|
import { VxeTableInstance, VxeTablePropTypes } from 'vxe-table';
|
||||||
import { TaskListenerVO } from 'bpmnDesign';
|
import { ParamVO, TaskListenerVO } from 'bpmnDesign';
|
||||||
|
import usePanel from '@/components/BpmnDesign/hooks/usePanel';
|
||||||
|
import useDialog from '@/hooks/useDialog';
|
||||||
|
|
||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
@ -94,13 +105,15 @@ const props = withDefaults(defineProps<PropType>(), {
|
|||||||
categorys: () => []
|
categorys: () => []
|
||||||
});
|
});
|
||||||
|
|
||||||
const elementType = computed(() => {
|
const { title, visible, openDialog, closeDialog } = useDialog({
|
||||||
const bizObj = props.element.businessObject;
|
title: '任务监听器'
|
||||||
return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type;
|
});
|
||||||
|
const { showConfig, elementType, updateProperties } = usePanel({
|
||||||
|
modeler: props.modeler,
|
||||||
|
element: toRaw(props.element)
|
||||||
});
|
});
|
||||||
const config = computed(() => showConfig[elementType.value] || {});
|
|
||||||
|
|
||||||
const visible = ref(false);
|
const listenerParamRef = ref<InstanceType<typeof ListenerParam>>();
|
||||||
const tableRef = ref<VxeTableInstance<TaskListenerVO>>();
|
const tableRef = ref<VxeTableInstance<TaskListenerVO>>();
|
||||||
const currentIndex = ref(0);
|
const currentIndex = ref(0);
|
||||||
const tableData = ref<TaskListenerVO[]>([]);
|
const tableData = ref<TaskListenerVO[]>([]);
|
||||||
@ -126,18 +139,21 @@ const eventSelect = [
|
|||||||
const configParam = (i: number) => {
|
const configParam = (i: number) => {
|
||||||
currentIndex.value = i;
|
currentIndex.value = i;
|
||||||
showParamDialog.value = true;
|
showParamDialog.value = true;
|
||||||
|
listenerParamRef.value.openDialog();
|
||||||
};
|
};
|
||||||
const insertRow = async () => {
|
const insertRow = async () => {
|
||||||
const $table = tableRef.value;
|
const $table = tableRef.value;
|
||||||
if ($table) {
|
if ($table) {
|
||||||
tableData.value.push({
|
const { row: newRow } = await $table.insertAt(
|
||||||
|
{
|
||||||
className: '',
|
className: '',
|
||||||
type: '',
|
type: '',
|
||||||
name: '',
|
name: '',
|
||||||
event: '',
|
event: '',
|
||||||
params: []
|
params: []
|
||||||
});
|
},
|
||||||
const { row: newRow } = await $table.insertAt({}, -1);
|
-1
|
||||||
|
);
|
||||||
// 插入一条数据并触发校验
|
// 插入一条数据并触发校验
|
||||||
await $table.validate(newRow);
|
await $table.validate(newRow);
|
||||||
}
|
}
|
||||||
@ -164,7 +180,6 @@ const submitForm = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const open = () => (visible.value = true);
|
|
||||||
const updateElement = () => {
|
const updateElement = () => {
|
||||||
if (tableData.value.length) {
|
if (tableData.value.length) {
|
||||||
let extensionElements = props.element.businessObject.get('extensionElements');
|
let extensionElements = props.element.businessObject.get('extensionElements');
|
||||||
@ -199,12 +214,8 @@ const updateElement = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProperties = (properties: any) => {
|
|
||||||
const modeling = props.modeler.get('modeling');
|
|
||||||
modeling.updateProperties(toRaw(props.element), properties);
|
|
||||||
};
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open
|
openDialog
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
25
src/hooks/useDialog.ts
Normal file
25
src/hooks/useDialog.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
export default (ops?: Options) => {
|
||||||
|
const visible = ref(false);
|
||||||
|
const title = ref(ops.title || '');
|
||||||
|
|
||||||
|
const openDialog = () => {
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
visible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
visible,
|
||||||
|
|
||||||
|
openDialog,
|
||||||
|
closeDialog
|
||||||
|
};
|
||||||
|
};
|
@ -33,6 +33,9 @@ import i18n from '@/lang/index';
|
|||||||
// vxeTable
|
// vxeTable
|
||||||
import VXETable from 'vxe-table';
|
import VXETable from 'vxe-table';
|
||||||
import 'vxe-table/lib/style.css';
|
import 'vxe-table/lib/style.css';
|
||||||
|
VXETable.config({
|
||||||
|
zIndex: 999999
|
||||||
|
});
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
14
src/types/bpmn.d.ts
vendored
14
src/types/bpmn.d.ts
vendored
@ -12,4 +12,18 @@ declare module 'bpmnDesign' {
|
|||||||
className: string;
|
className: string;
|
||||||
params: ParamVO[];
|
params: ParamVO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExecutionListenerVO {
|
||||||
|
event: string;
|
||||||
|
type: string;
|
||||||
|
className: string;
|
||||||
|
params: ParamVO[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProcessPanel {
|
||||||
|
processCategory: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user