!297 Merge remote-tracking branch 'yudao/dev' into dev
Merge pull request !297 from Jason/dev
This commit is contained in:
@@ -1,44 +1,23 @@
|
|||||||
<script lang="ts" setup>
|
<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 { confirm, useVbenModal } from '@vben/common-ui';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import {
|
import { Button, Divider, message } from 'ant-design-vue';
|
||||||
Button,
|
|
||||||
Divider,
|
|
||||||
Form,
|
|
||||||
FormItem,
|
|
||||||
Input,
|
|
||||||
message,
|
|
||||||
} from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
import SignalMessageModal from './SignalMessageModal.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'SignalAndMassage' });
|
defineOptions({ name: 'SignalAndMassage' });
|
||||||
const signalList = ref<any[]>([]);
|
const signalList = ref<any[]>([]);
|
||||||
const messageList = ref<any[]>([]);
|
const messageList = ref<any[]>([]);
|
||||||
const modelType = ref('');
|
const modelType = ref<'message' | 'signal'>('message');
|
||||||
const modelObjectForm = ref<any>({});
|
|
||||||
const formRef = ref();
|
|
||||||
const rootElements = ref();
|
const rootElements = ref();
|
||||||
const messageIdMap = ref();
|
const messageIdMap = ref();
|
||||||
const signalIdMap = ref();
|
const signalIdMap = ref();
|
||||||
const editingIndex = ref(-1); // 正在编辑的索引,-1 表示新建
|
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;
|
const bpmnInstances = () => (window as any)?.bpmnInstances;
|
||||||
|
|
||||||
// 生成规范化的ID
|
// 生成规范化的ID
|
||||||
@@ -67,82 +46,78 @@ const initDataList = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const openModel = (type: any) => {
|
const openModel = (type: 'message' | 'signal') => {
|
||||||
modelType.value = type;
|
modelType.value = type;
|
||||||
editingIndex.value = -1;
|
editingIndex.value = -1;
|
||||||
modelObjectForm.value = {
|
modalApi
|
||||||
id: generateStandardId(type),
|
.setData({
|
||||||
name: '',
|
id: generateStandardId(type),
|
||||||
};
|
isEdit: false,
|
||||||
modelModalApi.open();
|
name: '',
|
||||||
|
type,
|
||||||
|
})
|
||||||
|
.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
const openEditModel = (type: any, row: any, index: number) => {
|
const openEditModel = (type: 'message' | 'signal', row: any, index: number) => {
|
||||||
modelType.value = type;
|
modelType.value = type;
|
||||||
editingIndex.value = index;
|
editingIndex.value = index;
|
||||||
modelObjectForm.value = { ...row };
|
modalApi
|
||||||
modelModalApi.open();
|
.setData({
|
||||||
|
id: row.id,
|
||||||
|
isEdit: true,
|
||||||
|
name: row.name,
|
||||||
|
type,
|
||||||
|
})
|
||||||
|
.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewObject = async () => {
|
const handleConfirm = (formData: { id: string; name: string }) => {
|
||||||
try {
|
|
||||||
await formRef.value?.validate();
|
|
||||||
} catch {
|
|
||||||
// 校验未通过,直接返回
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelType.value === 'message') {
|
if (modelType.value === 'message') {
|
||||||
// 编辑模式
|
|
||||||
if (editingIndex.value === -1) {
|
if (editingIndex.value === -1) {
|
||||||
// 新建模式
|
// 新建模式
|
||||||
if (messageIdMap.value[modelObjectForm.value.id]) {
|
if (messageIdMap.value[formData.id]) {
|
||||||
message.error('该消息已存在,请修改id后重新保存');
|
message.error('该消息已存在,请修改id后重新保存');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const messageRef = bpmnInstances().moddle.create(
|
const messageRef = bpmnInstances().moddle.create(
|
||||||
'bpmn:Message',
|
'bpmn:Message',
|
||||||
modelObjectForm.value,
|
formData,
|
||||||
);
|
);
|
||||||
rootElements.value.push(messageRef);
|
rootElements.value.push(messageRef);
|
||||||
} else {
|
} else {
|
||||||
|
// 编辑模式
|
||||||
const targetMessage = messageList.value[editingIndex.value];
|
const targetMessage = messageList.value[editingIndex.value];
|
||||||
// 查找 rootElements 中的原始对象
|
|
||||||
const rootMessage = rootElements.value.find(
|
const rootMessage = rootElements.value.find(
|
||||||
(el: any) => el.$type === 'bpmn:Message' && el.id === targetMessage.id,
|
(el: any) => el.$type === 'bpmn:Message' && el.id === targetMessage.id,
|
||||||
);
|
);
|
||||||
if (rootMessage) {
|
if (rootMessage) {
|
||||||
rootMessage.id = modelObjectForm.value.id;
|
rootMessage.id = formData.id;
|
||||||
rootMessage.name = modelObjectForm.value.name;
|
rootMessage.name = formData.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 编辑模式
|
|
||||||
if (editingIndex.value === -1) {
|
if (editingIndex.value === -1) {
|
||||||
// 新建模式
|
// 新建模式
|
||||||
if (signalIdMap.value[modelObjectForm.value.id]) {
|
if (signalIdMap.value[formData.id]) {
|
||||||
message.error('该信号已存在,请修改id后重新保存');
|
message.error('该信号已存在,请修改id后重新保存');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const signalRef = bpmnInstances().moddle.create(
|
const signalRef = bpmnInstances().moddle.create('bpmn:Signal', formData);
|
||||||
'bpmn:Signal',
|
|
||||||
modelObjectForm.value,
|
|
||||||
);
|
|
||||||
rootElements.value.push(signalRef);
|
rootElements.value.push(signalRef);
|
||||||
} else {
|
} else {
|
||||||
|
// 编辑模式
|
||||||
const targetSignal = signalList.value[editingIndex.value];
|
const targetSignal = signalList.value[editingIndex.value];
|
||||||
// 查找 rootElements 中的原始对象
|
|
||||||
const rootSignal = rootElements.value.find(
|
const rootSignal = rootElements.value.find(
|
||||||
(el: any) => el.$type === 'bpmn:Signal' && el.id === targetSignal.id,
|
(el: any) => el.$type === 'bpmn:Signal' && el.id === targetSignal.id,
|
||||||
);
|
);
|
||||||
if (rootSignal) {
|
if (rootSignal) {
|
||||||
rootSignal.id = modelObjectForm.value.id;
|
rootSignal.id = formData.id;
|
||||||
rootSignal.name = modelObjectForm.value.name;
|
rootSignal.name = formData.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modelModalApi.close();
|
// 触发建模器更新以保存更改
|
||||||
// 触发建模器更新以保存更改。
|
|
||||||
saveChanges();
|
saveChanges();
|
||||||
initDataList();
|
initDataList();
|
||||||
};
|
};
|
||||||
@@ -250,9 +225,8 @@ const [SignalGrid, signalGridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [ModelModal, modelModalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
destroyOnClose: true,
|
connectedComponent: SignalMessageModal,
|
||||||
onConfirm: addNewObject,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -354,24 +328,6 @@ watch(
|
|||||||
</template>
|
</template>
|
||||||
</SignalGrid>
|
</SignalGrid>
|
||||||
|
|
||||||
<ModelModal :title="modelConfig.title" class="w-3/5">
|
<Modal @confirm="handleConfirm" />
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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,8 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { h, inject, nextTick, ref, toRaw, watch } from 'vue';
|
import { inject, nextTick, onMounted, ref, toRaw, watch } from 'vue';
|
||||||
|
|
||||||
import { alert } from '@vben/common-ui';
|
import { confirm, useVbenModal } from '@vben/common-ui';
|
||||||
import { PlusOutlined } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -10,12 +10,14 @@ import {
|
|||||||
Form,
|
Form,
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Select,
|
||||||
|
SelectOption,
|
||||||
Switch,
|
Switch,
|
||||||
Table,
|
|
||||||
TableColumn,
|
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
import { getModelList } from '#/api/bpm/model';
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
processInstanceName: string;
|
processInstanceName: string;
|
||||||
calledElement: string;
|
calledElement: string;
|
||||||
@@ -44,8 +46,7 @@ const inVariableList = ref<any[]>([]);
|
|||||||
const outVariableList = ref<any[]>([]);
|
const outVariableList = ref<any[]>([]);
|
||||||
const variableType = ref<string>(); // 参数类型
|
const variableType = ref<string>(); // 参数类型
|
||||||
const editingVariableIndex = ref<number>(-1); // 编辑参数下标
|
const editingVariableIndex = ref<number>(-1); // 编辑参数下标
|
||||||
const variableDialogVisible = ref<boolean>(false);
|
const varialbeFormRef = ref();
|
||||||
const varialbeFormRef = ref<any>();
|
|
||||||
const varialbeFormData = ref<{
|
const varialbeFormData = ref<{
|
||||||
source: string;
|
source: string;
|
||||||
target: string;
|
target: string;
|
||||||
@@ -57,10 +58,10 @@ const varialbeFormData = ref<{
|
|||||||
const bpmnInstances = () => (window as any)?.bpmnInstances;
|
const bpmnInstances = () => (window as any)?.bpmnInstances;
|
||||||
const bpmnElement = ref<any>();
|
const bpmnElement = ref<any>();
|
||||||
const otherExtensionList = ref<any[]>([]);
|
const otherExtensionList = ref<any[]>([]);
|
||||||
|
const childProcessOptions = ref<{ key: string; name: string }[]>([]);
|
||||||
|
|
||||||
const initCallActivity = () => {
|
const initCallActivity = () => {
|
||||||
bpmnElement.value = bpmnInstances().bpmnElement;
|
bpmnElement.value = bpmnInstances().bpmnElement;
|
||||||
// console.log(bpmnElement.value.businessObject, 'callActivity');
|
|
||||||
|
|
||||||
// 初始化所有配置项
|
// 初始化所有配置项
|
||||||
Object.keys(formData.value).forEach((key: string) => {
|
Object.keys(formData.value).forEach((key: string) => {
|
||||||
@@ -85,11 +86,6 @@ const initCallActivity = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 默认添加
|
|
||||||
// bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
|
||||||
// calledElementType: 'key'
|
|
||||||
// })
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateCallActivityAttr = (attr: keyof FormData) => {
|
const updateCallActivityAttr = (attr: keyof FormData) => {
|
||||||
@@ -98,16 +94,26 @@ const updateCallActivityAttr = (attr: keyof FormData) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [VariableModal, variableModalApi] = useVbenModal({
|
||||||
|
title: '参数配置',
|
||||||
|
onConfirm: () => {
|
||||||
|
saveVariable();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const openVariableForm = (type: string, data: any, index: number) => {
|
const openVariableForm = (type: string, data: any, index: number) => {
|
||||||
editingVariableIndex.value = index;
|
editingVariableIndex.value = index;
|
||||||
variableType.value = type;
|
variableType.value = type;
|
||||||
varialbeFormData.value = index === -1 ? {} : { ...data };
|
varialbeFormData.value = index === -1 ? {} : { ...data };
|
||||||
variableDialogVisible.value = true;
|
variableModalApi.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeVariable = async (type: string, index: number) => {
|
const removeVariable = async (type: string, index: number) => {
|
||||||
try {
|
try {
|
||||||
await alert('是否确认删除?');
|
await confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '是否确认删除?',
|
||||||
|
});
|
||||||
if (type === 'in') {
|
if (type === 'in') {
|
||||||
inVariableList.value.splice(index, 1);
|
inVariableList.value.splice(index, 1);
|
||||||
}
|
}
|
||||||
@@ -115,10 +121,19 @@ const removeVariable = async (type: string, index: number) => {
|
|||||||
outVariableList.value.splice(index, 1);
|
outVariableList.value.splice(index, 1);
|
||||||
}
|
}
|
||||||
updateElementExtensions();
|
updateElementExtensions();
|
||||||
} catch {}
|
} catch (error: any) {
|
||||||
|
console.error(`[removeVariable error ]: ${error.message || error}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveVariable = () => {
|
const saveVariable = async () => {
|
||||||
|
try {
|
||||||
|
await varialbeFormRef.value?.validate();
|
||||||
|
} catch {
|
||||||
|
// 验证失败直接返回
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (editingVariableIndex.value === -1) {
|
if (editingVariableIndex.value === -1) {
|
||||||
if (variableType.value === 'in') {
|
if (variableType.value === 'in') {
|
||||||
inVariableList.value.push(
|
inVariableList.value.push(
|
||||||
@@ -149,7 +164,7 @@ const saveVariable = () => {
|
|||||||
varialbeFormData.value.target;
|
varialbeFormData.value.target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
variableDialogVisible.value = false;
|
variableModalApi.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateElementExtensions = () => {
|
const updateElementExtensions = () => {
|
||||||
@@ -176,28 +191,93 @@ watch(
|
|||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
columns: [
|
||||||
|
{ title: '源', field: 'source', minWidth: 100 },
|
||||||
|
{ title: '目标', field: 'target', minWidth: 100 },
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 130,
|
||||||
|
slots: { default: 'action' },
|
||||||
|
fixed: 'right' as const,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
border: true,
|
||||||
|
showOverflow: true,
|
||||||
|
height: 'auto',
|
||||||
|
toolbarConfig: { enabled: false },
|
||||||
|
pagerConfig: { enabled: false },
|
||||||
|
};
|
||||||
|
|
||||||
|
const [InVariableGrid, inVariableGridApi] = useVbenVxeGrid({
|
||||||
|
gridOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [OutVariableGrid, outVariableGridApi] = useVbenVxeGrid({
|
||||||
|
gridOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用浅层监听,避免无限循环
|
||||||
|
watch(
|
||||||
|
() => [...inVariableList.value],
|
||||||
|
(val) => {
|
||||||
|
inVariableGridApi.setGridOptions({ data: val });
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [...outVariableList.value],
|
||||||
|
(val) => {
|
||||||
|
outVariableGridApi.setGridOptions({ data: val });
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 选择子流程, 更新 bpmn callActivity calledElement 和 processInstanceName 属性 */
|
||||||
|
const handleChildProcessChange = (key: any) => {
|
||||||
|
if (!key) return;
|
||||||
|
const selected = childProcessOptions.value.find((item) => item.key === key);
|
||||||
|
if (selected) {
|
||||||
|
formData.value.calledElement = selected.key;
|
||||||
|
formData.value.processInstanceName = selected.name;
|
||||||
|
updateCallActivityAttr('calledElement');
|
||||||
|
updateCallActivityAttr('processInstanceName');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
// 获取流程模型列表
|
||||||
|
const list = await getModelList(undefined);
|
||||||
|
childProcessOptions.value = list.map((item) => ({
|
||||||
|
key: item.key,
|
||||||
|
name: item.name,
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取子流程列表失败', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="-mx-2">
|
||||||
<Form>
|
<Form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
||||||
<FormItem label="实例名称">
|
<FormItem label="被调用子流程">
|
||||||
<Input
|
<Select
|
||||||
v-model:value="formData.processInstanceName"
|
|
||||||
allow-clear
|
|
||||||
placeholder="请输入实例名称"
|
|
||||||
@change="updateCallActivityAttr('processInstanceName')"
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<!-- TODO 需要可选择已存在的流程 -->
|
|
||||||
<FormItem label="被调用流程">
|
|
||||||
<Input
|
|
||||||
v-model:value="formData.calledElement"
|
v-model:value="formData.calledElement"
|
||||||
|
placeholder="请选择子流程"
|
||||||
allow-clear
|
allow-clear
|
||||||
placeholder="请输入被调用流程"
|
@change="handleChildProcessChange"
|
||||||
@change="updateCallActivityAttr('calledElement')"
|
>
|
||||||
/>
|
<SelectOption
|
||||||
|
v-for="item in childProcessOptions"
|
||||||
|
:key="item.key"
|
||||||
|
:value="item.key"
|
||||||
|
:label="item.name"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem label="继承变量">
|
<FormItem label="继承变量">
|
||||||
@@ -223,134 +303,115 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Divider />
|
<div
|
||||||
<div>
|
class="mb-1 mt-2 flex items-center justify-between border-t border-gray-200 pt-2"
|
||||||
<div class="mb-10px flex">
|
>
|
||||||
<span>输入参数</span>
|
<span class="flex items-center text-sm font-medium"> 输入参数 </span>
|
||||||
<Button
|
<Button
|
||||||
class="ml-auto"
|
class="flex items-center"
|
||||||
type="primary"
|
size="small"
|
||||||
:icon="h(PlusOutlined)"
|
type="link"
|
||||||
title="添加参数"
|
@click="openVariableForm('in', null, -1)"
|
||||||
size="small"
|
|
||||||
@click="openVariableForm('in', null, -1)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Table
|
|
||||||
:data-source="inVariableList"
|
|
||||||
:scroll="{ y: 240 }"
|
|
||||||
bordered
|
|
||||||
:pagination="false"
|
|
||||||
>
|
>
|
||||||
<TableColumn
|
<template #icon>
|
||||||
title="源"
|
<IconifyIcon icon="ep:plus" />
|
||||||
data-index="source"
|
</template>
|
||||||
:min-width="100"
|
添加参数
|
||||||
:ellipsis="true"
|
</Button>
|
||||||
/>
|
|
||||||
<TableColumn
|
|
||||||
title="目标"
|
|
||||||
data-index="target"
|
|
||||||
:min-width="100"
|
|
||||||
:ellipsis="true"
|
|
||||||
/>
|
|
||||||
<TableColumn title="操作" :width="110">
|
|
||||||
<template #default="{ record, index }">
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
@click="openVariableForm('in', record, index)"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</Button>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
size="small"
|
|
||||||
danger
|
|
||||||
@click="removeVariable('in', index)"
|
|
||||||
>
|
|
||||||
移除
|
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
</TableColumn>
|
|
||||||
</Table>
|
|
||||||
</div>
|
</div>
|
||||||
|
<InVariableGrid class="-mx-2 mb-4">
|
||||||
|
<template #action="{ row, rowIndex }">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="openVariableForm('in', row, rowIndex)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
@click="removeVariable('in', rowIndex)"
|
||||||
|
>
|
||||||
|
移除
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</InVariableGrid>
|
||||||
|
|
||||||
<Divider />
|
<div
|
||||||
<div>
|
class="mb-1 mt-2 flex items-center justify-between border-t border-gray-200 pt-2"
|
||||||
<div class="mb-10px flex">
|
>
|
||||||
<span>输出参数</span>
|
<span class="flex items-center text-sm font-medium"> 输出参数 </span>
|
||||||
<Button
|
<Button
|
||||||
class="ml-auto"
|
class="flex items-center"
|
||||||
type="primary"
|
size="small"
|
||||||
:icon="h(PlusOutlined)"
|
type="link"
|
||||||
title="添加参数"
|
@click="openVariableForm('out', null, -1)"
|
||||||
size="small"
|
|
||||||
@click="openVariableForm('out', null, -1)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Table
|
|
||||||
:data-source="outVariableList"
|
|
||||||
:scroll="{ y: 240 }"
|
|
||||||
bordered
|
|
||||||
:pagination="false"
|
|
||||||
>
|
>
|
||||||
<TableColumn
|
<template #icon>
|
||||||
title="源"
|
<IconifyIcon icon="lucide:plus" class="size-4" />
|
||||||
data-index="source"
|
</template>
|
||||||
:min-width="100"
|
添加参数
|
||||||
:ellipsis="true"
|
</Button>
|
||||||
/>
|
|
||||||
<TableColumn
|
|
||||||
title="目标"
|
|
||||||
data-index="target"
|
|
||||||
:min-width="100"
|
|
||||||
:ellipsis="true"
|
|
||||||
/>
|
|
||||||
<TableColumn title="操作" :width="110">
|
|
||||||
<template #default="{ record, index }">
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
@click="openVariableForm('out', record, index)"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</Button>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
size="small"
|
|
||||||
danger
|
|
||||||
@click="removeVariable('out', index)"
|
|
||||||
>
|
|
||||||
移除
|
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
</TableColumn>
|
|
||||||
</Table>
|
|
||||||
</div>
|
</div>
|
||||||
|
<OutVariableGrid class="-mx-2">
|
||||||
|
<template #action="{ row, rowIndex }">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="openVariableForm('out', row, rowIndex)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
@click="removeVariable('out', rowIndex)"
|
||||||
|
>
|
||||||
|
移除
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</OutVariableGrid>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<!-- 添加或修改参数 -->
|
<VariableModal>
|
||||||
<Modal
|
<Form
|
||||||
v-model:open="variableDialogVisible"
|
:model="varialbeFormData"
|
||||||
title="参数配置"
|
ref="varialbeFormRef"
|
||||||
:width="600"
|
:label-col="{ span: 4 }"
|
||||||
:destroy-on-close="true"
|
:wrapper-col="{ span: 18 }"
|
||||||
@ok="saveVariable"
|
>
|
||||||
@cancel="variableDialogVisible = false"
|
<FormItem
|
||||||
>
|
label="源"
|
||||||
<Form :model="varialbeFormData" ref="varialbeFormRef">
|
name="source"
|
||||||
<FormItem label="源:" name="source">
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '源不能为空',
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<Input v-model:value="varialbeFormData.source" allow-clear />
|
<Input v-model:value="varialbeFormData.source" allow-clear />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="目标:" name="target">
|
<FormItem
|
||||||
|
label="目标"
|
||||||
|
name="target"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '目标不能为空',
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<Input v-model:value="varialbeFormData.target" allow-clear />
|
<Input v-model:value="varialbeFormData.target" allow-clear />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</VariableModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|||||||
@@ -1,25 +1,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import { nextTick, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue';
|
||||||
h,
|
|
||||||
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 {
|
import { Button, message, Select, SelectOption } from 'ant-design-vue';
|
||||||
Button,
|
|
||||||
Form,
|
import SignalMessageModal from '../../signal-message/SignalMessageModal.vue';
|
||||||
Input,
|
|
||||||
message,
|
|
||||||
Modal,
|
|
||||||
Select,
|
|
||||||
SelectOption,
|
|
||||||
} from 'ant-design-vue';
|
|
||||||
|
|
||||||
defineOptions({ name: 'ReceiveTask' });
|
defineOptions({ name: 'ReceiveTask' });
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -28,40 +15,54 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const bindMessageId = ref('');
|
const bindMessageId = ref('');
|
||||||
const newMessageForm = ref<Record<string, any>>({});
|
|
||||||
const messageMap = ref<Record<string, any>>({});
|
const messageMap = ref<Record<string, any>>({});
|
||||||
const messageModelVisible = ref(false);
|
|
||||||
const bpmnElement = ref<any>();
|
const bpmnElement = ref<any>();
|
||||||
const bpmnMessageRefsMap = ref<Record<string, any>>();
|
const bpmnMessageRefsMap = ref<Record<string, any>>();
|
||||||
const bpmnRootElements = ref<any>();
|
const bpmnRootElements = ref<any>();
|
||||||
|
|
||||||
const bpmnInstances = () => (window as any).bpmnInstances;
|
const bpmnInstances = () => (window as any).bpmnInstances;
|
||||||
|
|
||||||
const getBindMessage = () => {
|
const getBindMessage = () => {
|
||||||
bpmnElement.value = bpmnInstances().bpmnElement;
|
bpmnElement.value = bpmnInstances().bpmnElement;
|
||||||
bindMessageId.value =
|
bindMessageId.value =
|
||||||
bpmnElement.value.businessObject?.messageRef?.id || '-1';
|
bpmnElement.value.businessObject?.messageRef?.id || '-1';
|
||||||
};
|
};
|
||||||
const openMessageModel = () => {
|
|
||||||
messageModelVisible.value = true;
|
/** 生成消息 ID */
|
||||||
newMessageForm.value = {};
|
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;
|
return;
|
||||||
}
|
}
|
||||||
const newMessage = bpmnInstances().moddle.create(
|
const newMessage = bpmnInstances().moddle.create('bpmn:Message', formData);
|
||||||
'bpmn:Message',
|
|
||||||
newMessageForm.value,
|
|
||||||
);
|
|
||||||
bpmnRootElements.value.push(newMessage);
|
bpmnRootElements.value.push(newMessage);
|
||||||
messageMap.value[newMessageForm.value.id] = newMessageForm.value.name;
|
messageMap.value[formData.id] = formData.name;
|
||||||
// @ts-ignore
|
|
||||||
if (bpmnMessageRefsMap.value) {
|
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) => {
|
const updateTaskMessage = (messageId: string) => {
|
||||||
if (messageId === '-1') {
|
if (messageId === '-1') {
|
||||||
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
||||||
@@ -96,7 +97,6 @@ onBeforeUnmount(() => {
|
|||||||
watch(
|
watch(
|
||||||
() => props.id,
|
() => props.id,
|
||||||
() => {
|
() => {
|
||||||
// bpmnElement.value = bpmnInstances().bpmnElement
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
getBindMessage();
|
getBindMessage();
|
||||||
});
|
});
|
||||||
@@ -106,56 +106,31 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div style="margin-top: 16px">
|
<div class="mt-2">
|
||||||
<Form.Item label="消息实例">
|
<div class="mb-2 flex justify-end">
|
||||||
<div
|
<Button type="link" size="small" class="p-0" @click="openCreateModal">
|
||||||
style="
|
<template #icon>
|
||||||
display: flex;
|
<IconifyIcon class="size-4" icon="lucide:plus" />
|
||||||
flex-wrap: nowrap;
|
</template>
|
||||||
align-items: center;
|
创建新消息
|
||||||
justify-content: space-between;
|
</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
|
<SelectOption
|
||||||
v-model:value="bindMessageId"
|
v-for="key in Object.keys(messageMap)"
|
||||||
@change="(value: any) => updateTaskMessage(value)"
|
:key="key"
|
||||||
|
:value="key"
|
||||||
>
|
>
|
||||||
<SelectOption
|
{{ messageMap[key] }}
|
||||||
v-for="key in Object.keys(messageMap)"
|
</SelectOption>
|
||||||
:value="key"
|
</Select>
|
||||||
:key="key"
|
</div>
|
||||||
>
|
<Modal @confirm="handleConfirm" />
|
||||||
{{ 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>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user