feat: [bpm][antd] bpm 设计器接收任务优化
This commit is contained in:
@@ -1,44 +1,23 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { confirm, useVbenModal } from '@vben/common-ui';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Form,
|
||||
FormItem,
|
||||
Input,
|
||||
message,
|
||||
} from 'ant-design-vue';
|
||||
import { Button, Divider, message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
|
||||
import SignalMessageModal from './SignalMessageModal.vue';
|
||||
|
||||
defineOptions({ name: 'SignalAndMassage' });
|
||||
const signalList = ref<any[]>([]);
|
||||
const messageList = ref<any[]>([]);
|
||||
const modelType = ref('');
|
||||
const modelObjectForm = ref<any>({});
|
||||
const formRef = ref();
|
||||
const modelType = ref<'message' | 'signal'>('message');
|
||||
const rootElements = ref();
|
||||
const messageIdMap = ref();
|
||||
const signalIdMap = ref();
|
||||
const editingIndex = ref(-1); // 正在编辑的索引,-1 表示新建
|
||||
const modelConfig = computed(() => {
|
||||
const isEdit = editingIndex.value !== -1;
|
||||
return modelType.value === 'message'
|
||||
? {
|
||||
title: isEdit ? '编辑消息' : '创建消息',
|
||||
idLabel: '消息ID',
|
||||
nameLabel: '消息名称',
|
||||
}
|
||||
: {
|
||||
title: isEdit ? '编辑信号' : '创建信号',
|
||||
idLabel: '信号ID',
|
||||
nameLabel: '信号名称',
|
||||
};
|
||||
});
|
||||
const bpmnInstances = () => (window as any)?.bpmnInstances;
|
||||
|
||||
// 生成规范化的ID
|
||||
@@ -67,82 +46,78 @@ const initDataList = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const openModel = (type: any) => {
|
||||
const openModel = (type: 'message' | 'signal') => {
|
||||
modelType.value = type;
|
||||
editingIndex.value = -1;
|
||||
modelObjectForm.value = {
|
||||
id: generateStandardId(type),
|
||||
name: '',
|
||||
};
|
||||
modelModalApi.open();
|
||||
modalApi
|
||||
.setData({
|
||||
id: generateStandardId(type),
|
||||
isEdit: false,
|
||||
name: '',
|
||||
type,
|
||||
})
|
||||
.open();
|
||||
};
|
||||
|
||||
const openEditModel = (type: any, row: any, index: number) => {
|
||||
const openEditModel = (type: 'message' | 'signal', row: any, index: number) => {
|
||||
modelType.value = type;
|
||||
editingIndex.value = index;
|
||||
modelObjectForm.value = { ...row };
|
||||
modelModalApi.open();
|
||||
modalApi
|
||||
.setData({
|
||||
id: row.id,
|
||||
isEdit: true,
|
||||
name: row.name,
|
||||
type,
|
||||
})
|
||||
.open();
|
||||
};
|
||||
|
||||
const addNewObject = async () => {
|
||||
try {
|
||||
await formRef.value?.validate();
|
||||
} catch {
|
||||
// 校验未通过,直接返回
|
||||
return;
|
||||
}
|
||||
|
||||
const handleConfirm = (formData: { id: string; name: string }) => {
|
||||
if (modelType.value === 'message') {
|
||||
// 编辑模式
|
||||
if (editingIndex.value === -1) {
|
||||
// 新建模式
|
||||
if (messageIdMap.value[modelObjectForm.value.id]) {
|
||||
if (messageIdMap.value[formData.id]) {
|
||||
message.error('该消息已存在,请修改id后重新保存');
|
||||
return;
|
||||
}
|
||||
const messageRef = bpmnInstances().moddle.create(
|
||||
'bpmn:Message',
|
||||
modelObjectForm.value,
|
||||
formData,
|
||||
);
|
||||
rootElements.value.push(messageRef);
|
||||
} else {
|
||||
// 编辑模式
|
||||
const targetMessage = messageList.value[editingIndex.value];
|
||||
// 查找 rootElements 中的原始对象
|
||||
const rootMessage = rootElements.value.find(
|
||||
(el: any) => el.$type === 'bpmn:Message' && el.id === targetMessage.id,
|
||||
);
|
||||
if (rootMessage) {
|
||||
rootMessage.id = modelObjectForm.value.id;
|
||||
rootMessage.name = modelObjectForm.value.name;
|
||||
rootMessage.id = formData.id;
|
||||
rootMessage.name = formData.name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 编辑模式
|
||||
if (editingIndex.value === -1) {
|
||||
// 新建模式
|
||||
if (signalIdMap.value[modelObjectForm.value.id]) {
|
||||
if (signalIdMap.value[formData.id]) {
|
||||
message.error('该信号已存在,请修改id后重新保存');
|
||||
return;
|
||||
}
|
||||
const signalRef = bpmnInstances().moddle.create(
|
||||
'bpmn:Signal',
|
||||
modelObjectForm.value,
|
||||
);
|
||||
const signalRef = bpmnInstances().moddle.create('bpmn:Signal', formData);
|
||||
rootElements.value.push(signalRef);
|
||||
} else {
|
||||
// 编辑模式
|
||||
const targetSignal = signalList.value[editingIndex.value];
|
||||
// 查找 rootElements 中的原始对象
|
||||
const rootSignal = rootElements.value.find(
|
||||
(el: any) => el.$type === 'bpmn:Signal' && el.id === targetSignal.id,
|
||||
);
|
||||
if (rootSignal) {
|
||||
rootSignal.id = modelObjectForm.value.id;
|
||||
rootSignal.name = modelObjectForm.value.name;
|
||||
rootSignal.id = formData.id;
|
||||
rootSignal.name = formData.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
modelModalApi.close();
|
||||
// 触发建模器更新以保存更改。
|
||||
// 触发建模器更新以保存更改
|
||||
saveChanges();
|
||||
initDataList();
|
||||
};
|
||||
@@ -250,9 +225,8 @@ const [SignalGrid, signalGridApi] = useVbenVxeGrid({
|
||||
},
|
||||
});
|
||||
|
||||
const [ModelModal, modelModalApi] = useVbenModal({
|
||||
destroyOnClose: true,
|
||||
onConfirm: addNewObject,
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
connectedComponent: SignalMessageModal,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
@@ -354,24 +328,6 @@ watch(
|
||||
</template>
|
||||
</SignalGrid>
|
||||
|
||||
<ModelModal :title="modelConfig.title" class="w-3/5">
|
||||
<Form
|
||||
:model="modelObjectForm"
|
||||
ref="formRef"
|
||||
:label-col="{ span: 4 }"
|
||||
:wrapper-col="{ span: 18 }"
|
||||
>
|
||||
<FormItem
|
||||
:label="modelConfig.idLabel"
|
||||
name="id"
|
||||
:rules="[{ required: true, message: '请输入 ID' }]"
|
||||
>
|
||||
<Input v-model:value="modelObjectForm.id" allow-clear />
|
||||
</FormItem>
|
||||
<FormItem :label="modelConfig.nameLabel">
|
||||
<Input v-model:value="modelObjectForm.name" allow-clear />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</ModelModal>
|
||||
<Modal @confirm="handleConfirm" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Form, FormItem, Input } from 'ant-design-vue';
|
||||
|
||||
defineOptions({ name: 'SignalMessageModal' });
|
||||
|
||||
const emit = defineEmits<{
|
||||
confirm: [data: { id: string; name: string }];
|
||||
}>();
|
||||
|
||||
const formRef = ref();
|
||||
const form = ref<{ id: string; name: string }>({ id: '', name: '' });
|
||||
const modelType = ref<'message' | 'signal'>('message');
|
||||
const isEdit = ref(false);
|
||||
|
||||
const config = computed(() => {
|
||||
return modelType.value === 'message'
|
||||
? {
|
||||
title: isEdit.value ? '编辑消息' : '创建消息',
|
||||
idLabel: '消息 ID',
|
||||
nameLabel: '消息名称',
|
||||
}
|
||||
: {
|
||||
title: isEdit.value ? '编辑信号' : '创建信号',
|
||||
idLabel: '信号 ID',
|
||||
nameLabel: '信号名称',
|
||||
};
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
onOpenChange(isOpen) {
|
||||
if (isOpen) {
|
||||
const data = modalApi.getData<{
|
||||
id?: string;
|
||||
isEdit?: boolean;
|
||||
name?: string;
|
||||
type: 'message' | 'signal';
|
||||
}>();
|
||||
modelType.value = data?.type || 'message';
|
||||
isEdit.value = data?.isEdit || false;
|
||||
form.value = {
|
||||
id: data?.id || '',
|
||||
name: data?.name || '',
|
||||
};
|
||||
// 清除校验
|
||||
setTimeout(() => {
|
||||
formRef.value?.clearValidate();
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
async onConfirm() {
|
||||
try {
|
||||
await formRef.value?.validate();
|
||||
emit('confirm', { ...form.value });
|
||||
modalApi.close();
|
||||
} catch {
|
||||
// 校验未通过
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="config.title" class="w-3/5">
|
||||
<Form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:label-col="{ span: 4 }"
|
||||
:wrapper-col="{ span: 18 }"
|
||||
>
|
||||
<FormItem
|
||||
:label="config.idLabel"
|
||||
name="id"
|
||||
:rules="[{ required: true, message: '请输入 ID' }]"
|
||||
>
|
||||
<Input v-model:value="form.id" allow-clear />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
:label="config.nameLabel"
|
||||
name="name"
|
||||
:rules="[{ required: true, message: '请输入名称' }]"
|
||||
>
|
||||
<Input v-model:value="form.name" allow-clear />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -1,25 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
h,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
ref,
|
||||
toRaw,
|
||||
watch,
|
||||
} from 'vue';
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue';
|
||||
|
||||
import { PlusOutlined } from '@vben/icons';
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
Modal,
|
||||
Select,
|
||||
SelectOption,
|
||||
} from 'ant-design-vue';
|
||||
import { Button, message, Select, SelectOption } from 'ant-design-vue';
|
||||
|
||||
import SignalMessageModal from '../../signal-message/SignalMessageModal.vue';
|
||||
|
||||
defineOptions({ name: 'ReceiveTask' });
|
||||
const props = defineProps({
|
||||
@@ -28,40 +15,54 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const bindMessageId = ref('');
|
||||
const newMessageForm = ref<Record<string, any>>({});
|
||||
const messageMap = ref<Record<string, any>>({});
|
||||
const messageModelVisible = ref(false);
|
||||
const bpmnElement = ref<any>();
|
||||
const bpmnMessageRefsMap = ref<Record<string, any>>();
|
||||
const bpmnRootElements = ref<any>();
|
||||
|
||||
const bpmnInstances = () => (window as any).bpmnInstances;
|
||||
|
||||
const getBindMessage = () => {
|
||||
bpmnElement.value = bpmnInstances().bpmnElement;
|
||||
bindMessageId.value =
|
||||
bpmnElement.value.businessObject?.messageRef?.id || '-1';
|
||||
};
|
||||
const openMessageModel = () => {
|
||||
messageModelVisible.value = true;
|
||||
newMessageForm.value = {};
|
||||
|
||||
/** 生成消息 ID */
|
||||
const generateMessageId = (): string => {
|
||||
const timestamp = Date.now();
|
||||
const random = Math.random().toString(36).slice(2, 6).toUpperCase();
|
||||
return `Message_${timestamp}_${random}`;
|
||||
};
|
||||
const createNewMessage = () => {
|
||||
if (messageMap.value[newMessageForm.value.id]) {
|
||||
message.error('该消息已存在,请修改id后重新保存');
|
||||
|
||||
/** 打开创建消息弹窗 */
|
||||
const openCreateModal = () => {
|
||||
modalApi
|
||||
.setData({
|
||||
id: generateMessageId(),
|
||||
isEdit: false,
|
||||
name: '',
|
||||
type: 'message',
|
||||
})
|
||||
.open();
|
||||
};
|
||||
|
||||
const handleConfirm = (formData: { id: string; name: string }) => {
|
||||
if (messageMap.value[formData.id]) {
|
||||
message.error('该消息已存在, 请修改id后重新保存');
|
||||
return;
|
||||
}
|
||||
const newMessage = bpmnInstances().moddle.create(
|
||||
'bpmn:Message',
|
||||
newMessageForm.value,
|
||||
);
|
||||
const newMessage = bpmnInstances().moddle.create('bpmn:Message', formData);
|
||||
bpmnRootElements.value.push(newMessage);
|
||||
messageMap.value[newMessageForm.value.id] = newMessageForm.value.name;
|
||||
// @ts-ignore
|
||||
messageMap.value[formData.id] = formData.name;
|
||||
if (bpmnMessageRefsMap.value) {
|
||||
bpmnMessageRefsMap.value[newMessageForm.value.id] = newMessage;
|
||||
bpmnMessageRefsMap.value[formData.id] = newMessage;
|
||||
}
|
||||
messageModelVisible.value = false;
|
||||
};
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
connectedComponent: SignalMessageModal,
|
||||
});
|
||||
const updateTaskMessage = (messageId: string) => {
|
||||
if (messageId === '-1') {
|
||||
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
||||
@@ -96,7 +97,6 @@ onBeforeUnmount(() => {
|
||||
watch(
|
||||
() => props.id,
|
||||
() => {
|
||||
// bpmnElement.value = bpmnInstances().bpmnElement
|
||||
nextTick(() => {
|
||||
getBindMessage();
|
||||
});
|
||||
@@ -106,56 +106,31 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="margin-top: 16px">
|
||||
<Form.Item label="消息实例">
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
"
|
||||
<div class="mt-2">
|
||||
<div class="mb-2 flex justify-end">
|
||||
<Button type="link" size="small" class="p-0" @click="openCreateModal">
|
||||
<template #icon>
|
||||
<IconifyIcon class="size-4" icon="lucide:plus" />
|
||||
</template>
|
||||
创建新消息
|
||||
</Button>
|
||||
</div>
|
||||
<div class="mb-1 flex items-center">
|
||||
<span class="w-20 text-foreground">消息实例:</span>
|
||||
<Select
|
||||
v-model:value="bindMessageId"
|
||||
class="w-full"
|
||||
@change="(value: any) => updateTaskMessage(value)"
|
||||
>
|
||||
<Select
|
||||
v-model:value="bindMessageId"
|
||||
@change="(value: any) => updateTaskMessage(value)"
|
||||
<SelectOption
|
||||
v-for="key in Object.keys(messageMap)"
|
||||
:key="key"
|
||||
:value="key"
|
||||
>
|
||||
<SelectOption
|
||||
v-for="key in Object.keys(messageMap)"
|
||||
:value="key"
|
||||
:key="key"
|
||||
>
|
||||
{{ messageMap[key] }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
<Button
|
||||
type="primary"
|
||||
:icon="h(PlusOutlined)"
|
||||
style="margin-left: 8px"
|
||||
@click="openMessageModel"
|
||||
/>
|
||||
</div>
|
||||
</Form.Item>
|
||||
<Modal
|
||||
v-model:open="messageModelVisible"
|
||||
:mask-closable="false"
|
||||
title="创建新消息"
|
||||
width="400px"
|
||||
:destroy-on-close="true"
|
||||
>
|
||||
<Form :model="newMessageForm" size="small">
|
||||
<Form.Item label="消息ID">
|
||||
<Input v-model:value="newMessageForm.id" allow-clear />
|
||||
</Form.Item>
|
||||
<Form.Item label="消息名称">
|
||||
<Input v-model:value="newMessageForm.name" allow-clear />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<template #footer>
|
||||
<Button size="small" type="primary" @click="createNewMessage">
|
||||
确 认
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
{{ messageMap[key] }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
</div>
|
||||
<Modal @confirm="handleConfirm" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user