review:【antd/ele】【bpm】流程模型的迁移

This commit is contained in:
YunaiV
2025-12-21 22:41:03 +08:00
parent bc654c9d45
commit 835da00f2c
39 changed files with 85 additions and 62 deletions

View File

@@ -32,7 +32,7 @@ const [Modal, modalApi] = useVbenModal({
try {
await formRef.value?.validate();
emit('confirm', { ...form.value });
modalApi.close();
await modalApi.close();
} catch {
// validate failed
}

View File

@@ -193,7 +193,6 @@ const childFormFieldOptions = ref<any[]>([]);
const saveConfig = async () => {
activeTabName.value = 'child';
if (!formRef.value) return false;
const valid = await formRef.value.validate().catch(() => false);
if (!valid) return false;

View File

@@ -137,7 +137,7 @@ const {
} = useNodeForm(BpmNodeTypeEnum.COPY_TASK_NODE);
const configForm = tempConfigForm as Ref<CopyTaskFormType>;
// 抄送人策略, 去掉发起人自选 和 发起人自己
// 抄送人策略,去掉发起人自选 和 发起人自己
const copyUserStrategies = computed(() => {
return CANDIDATE_STRATEGY.filter(
(item) => item.value !== CandidateStrategy.START_USER,

View File

@@ -348,7 +348,7 @@ function getShowText(): string {
return showText;
}
/** 显示触发器节点配置, 由父组件传过来 */
/** 显示触发器节点配置,由父组件传过来 */
function showTriggerNodeConfig(node: SimpleFlowNode) {
nodeName.value = node.name;
originalSetting = node.triggerSetting

View File

@@ -532,7 +532,7 @@ function useTimeoutHandler() {
if (timeUnit.value === TimeUnitType.HOUR) {
configForm.value.timeDuration = 6;
}
// 天, 默认 1天
// 天, 默认 1
if (timeUnit.value === TimeUnitType.DAY) {
configForm.value.timeDuration = 1;
}

View File

@@ -19,7 +19,7 @@ const props = defineProps<{
flowNode: SimpleFlowNode;
}>();
/** 定义事件,更新父组件 */
/** 定义事件,更新父组件 */
const emits = defineEmits<{
'update:flowNode': [node: SimpleFlowNode | undefined];
}>();

View File

@@ -22,7 +22,7 @@ const props = defineProps({
required: true,
},
});
// 定义事件,更新父组件
// 定义事件,更新父组件
const emits = defineEmits<{
'update:flowNode': [node: SimpleFlowNode | undefined];
}>();

View File

@@ -20,7 +20,7 @@ const props = defineProps({
required: true,
},
});
// 定义事件,更新父组件
// 定义事件,更新父组件
const emits = defineEmits<{
'update:flowNode': [node: SimpleFlowNode | undefined];
}>();

View File

@@ -289,7 +289,7 @@ function recursiveFindParentNode(
:condition-node="item"
:ref="item.id"
/>
<!-- 递归显示子节点 -->
<!-- 递归显示子节点 -->
<ProcessNodeTree
v-if="item && item.childNode"
:parent-node="item"

View File

@@ -291,7 +291,7 @@ function recursiveFindParentNode(
:condition-node="item"
:ref="item.id"
/>
<!-- 递归显示子节点 -->
<!-- 递归显示子节点 -->
<ProcessNodeTree
v-if="item && item.childNode"
:parent-node="item"

View File

@@ -53,10 +53,10 @@ const showInputs = ref<boolean[]>([]);
watch(
showInputs,
(newValues) => {
// 当输入框显示时, 自动聚焦
// 当输入框显示时 自动聚焦
newValues.forEach((value, index) => {
if (value) {
// 当显示状态从 false 变为 true 时, 自动聚焦
// 当显示状态从 false 变为 true 时 自动聚焦
nextTick(() => {
inputRefs.value[index]?.focus();
});
@@ -212,7 +212,7 @@ function recursiveFindParentNode(
/>
</div>
</div>
<!-- 递归显示子节点 -->
<!-- 递归显示子节点 -->
<ProcessNodeTree
v-if="item && item.childNode"
:parent-node="item"

View File

@@ -27,7 +27,7 @@ const props = defineProps({
},
});
// 定义事件,更新父组件
// 定义事件,更新父组件
defineEmits<{
'update:modelValue': [node: SimpleFlowNode | undefined];
}>();

View File

@@ -17,6 +17,7 @@ import { router } from '#/router';
import { useGridColumns, useGridFormSchema } from './data';
// TODO @jason这里是不是要迁移下
/** 刷新表格 */
function handleRefresh() {
gridApi.query();

View File

@@ -16,6 +16,7 @@ const emit = defineEmits<{
select: [expression: BpmProcessExpressionApi.ProcessExpression];
}>();
// TODO @jason这里是不是要迁移下
// 查询参数
const queryParams = ref({
status: CommonStatusEnum.ENABLE,

View File

@@ -18,6 +18,7 @@ const emit = defineEmits<{
select: [listener: BpmProcessListenerApi.ProcessListener];
}>();
// TODO @jason这里是不是要迁移下
// 查询参数
const queryParams = ref({
type: '',

View File

@@ -3,9 +3,7 @@ import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
// TODO @puhui999样式问题设计器那位置不太对
export { default as MyProcessDesigner } from './designer';
// TODO @puhui999流程发起时预览相关的需要使用
export { default as MyProcessViewer } from './designer/index2';
export { default as MyProcessPenal } from './penal';

View File

@@ -32,7 +32,7 @@ const [Modal, modalApi] = useVbenModal({
try {
await formRef.value?.validate();
emit('confirm', { ...form.value });
modalApi.close();
await modalApi.close();
} catch {
// validate failed
}

View File

@@ -65,6 +65,7 @@ watch(
<div class="panel-tab__content">
<ElForm>
<!-- add by 芋艿由于异步延续暂时用不到所以这里 display none -->
<!-- TODO @jaosn这里 antd 属性地 hidden需要关注么 -->
<ElFormItem label="异步延续" class="!hidden">
<ElCheckbox
v-model="taskConfigForm.asyncBefore"

View File

@@ -43,6 +43,7 @@ import {
MULTI_LEVEL_DEPT,
} from '#/views/bpm/components/simple-process-design/consts';
import { useFormFieldsPermission } from '#/views/bpm/components/simple-process-design/helpers';
// TODO @jasonantd 是不是导入对齐这个?
import { ProcessExpressionSelectModal } from '#/views/bpm/processExpression/components';
defineOptions({ name: 'UserTask' });

View File

@@ -28,6 +28,7 @@ const bpmnInstances = () => (window as any).bpmnInstances;
const type: Ref<string> = ref('time');
const condition: Ref<string> = ref('');
const valid: Ref<boolean> = ref(false);
// TODO @jasonconst dateValue = ref<Dayjs>(); 需要么?
const dateValue = ref();
const placeholder = computed<string>(() => {
@@ -106,6 +107,7 @@ function validate(): boolean {
// 选择时间 Modal
const [DateModal, dateModalApi] = useVbenModal({
title: '选择时间',
// TODO @jasonantd 这里有个属性,需要么?
onConfirm: onDateConfirm,
});
@@ -123,6 +125,7 @@ function onDateConfirm(): void {
// 持续时长 Modal
const [DurationModal, durationModalApi] = useVbenModal({
title: '时间配置',
// TODO @jasonantd 这里有个属性,需要么?
onConfirm: onDurationConfirm,
});
@@ -137,6 +140,7 @@ function onDurationConfirm(): void {
// 循环配置 Modal
const [CycleModal, cycleModalApi] = useVbenModal({
title: '时间配置',
// TODO @jasonantd 这里有个属性,需要么?
onConfirm: onCycleConfirm,
});

View File

@@ -194,10 +194,10 @@ const saveConfig = async () => {
// 3. 是否跳过发起人
currentNode.value.childProcessSetting.skipStartUserNode =
configForm.value.skipStartUserNode;
// 4. 主子变量
// 4. 主->子变量
currentNode.value.childProcessSetting.inVariables =
configForm.value.inVariables;
// 5. 子主变量
// 5. 子->主变量
currentNode.value.childProcessSetting.outVariables =
configForm.value.outVariables;
// 6. 发起人设置
@@ -256,9 +256,9 @@ const showChildProcessNodeConfig = (node: SimpleFlowNode) => {
// 3. 是否跳过发起人
configForm.value.skipStartUserNode =
node.childProcessSetting.skipStartUserNode;
// 4. 主流程→子流程变量
// 4. 主->子变量
configForm.value.inVariables = node.childProcessSetting.inVariables ?? [];
// 5. 子流程→主流程变量
// 5. 子->主变量
configForm.value.outVariables = node.childProcessSetting.outVariables ?? [];
// 6. 发起人设置
configForm.value.startUserType =

View File

@@ -96,7 +96,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
});
function open() {
// 使用三元表达式代替if-else解决linter 警告
// 使用三元表达式代替 if-else解决 linter 警告
condition.value = currentNode.value.conditionSetting
? cloneDeep(currentNode.value.conditionSetting)
: {
@@ -132,7 +132,7 @@ watch(
const showInput = ref(false);
// 输入框的引用
const inputRef = ref<HTMLInputElement | null>(null);
// 监听 showInput 的变化当变为true 时自动聚焦
// 监听 showInput 的变化,当变为 true 时自动聚焦
watch(showInput, (value) => {
if (value) {
nextTick(() => {
@@ -158,6 +158,7 @@ function changeNodeName() {
defineExpose({ open }); // 提供 open 方法,用于打开弹窗
</script>
<template>
<!-- TODO @jasonantd 1/3这里要统一么 -->
<Drawer class="w-2/5">
<template #title>
<div class="flex items-center">

View File

@@ -40,6 +40,7 @@ defineOptions({
const props = defineProps({
modelValue: {
type: Object,
// TODO @jason这里 required: false,
default: () => ({}),
},
});

View File

@@ -262,7 +262,7 @@ function updateFormFieldKey(
formSetting.updateFormFields[String(newKey)] = value;
}
/** 删除修改字段设置 */
/** 删除修改字段设置 */
function deleteFormFieldSetting(formSetting: FormTriggerSetting, key: string) {
if (!formSetting?.updateFormFields) return;
delete formSetting.updateFormFields[key];
@@ -383,6 +383,7 @@ onMounted(() => {
});
</script>
<template>
<!-- TODO @jasonantd 这里是 1/3需要保持一致么 -->
<Drawer class="w-2/5">
<template #title>
<div class="config-header">

View File

@@ -373,7 +373,7 @@ function showUserTaskNodeConfig(node: SimpleFlowNode) {
return;
}
// 2.1 审批人设置策略
// 2.1 审批人设置
configForm.value.candidateStrategy = node.candidateStrategy!;
// 解析候选人参数
parseCandidateParam(node.candidateStrategy!, node?.candidateParam);
@@ -402,7 +402,7 @@ function showUserTaskNodeConfig(node: SimpleFlowNode) {
// 2.5 设置审批人为空时
configForm.value.assignEmptyHandlerType = node.assignEmptyHandler?.type;
configForm.value.assignEmptyHandlerUserIds = node.assignEmptyHandler?.userIds;
// 2.6 设置用户任务的审批人与发起人相同处理
// 2.6 设置用户任务的审批人与发起人相同
configForm.value.assignStartUserHandlerType = node.assignStartUserHandlerType;
// 3. 操作按钮设置
buttonsSetting.value =
@@ -456,7 +456,7 @@ function useButtonsSetting() {
const changeBtnDisplayName = (index: number) => {
btnDisplayNameEdit.value[index] = true;
// 输入框自动聚
// 输入框自动聚
nextTick(() => {
if (_btnDisplayNameInputRefs.value[index]) {
_btnDisplayNameInputRefs.value[index]?.focus();
@@ -533,7 +533,7 @@ function useTimeoutHandler() {
configForm.value.timeDuration = 1;
}
};
// 超时时间 ISO 表示
// 超时时间 ISO 表示
const isoTimeDuration = computed(() => {
if (!configForm.value.timeoutHandlerEnable) {
return undefined;
@@ -586,12 +586,12 @@ function updatePermission(type: string) {
});
}
// 在组件初始化时记录初始
// 在组件初始化时记录初始位置
onMounted(() => {
// 固定添加发起人ID字段
formFieldOptions.unshift({
field: ProcessVariableEnum.START_USER_ID,
title: '发起人ID',
title: '发起人',
type: 'UserSelect',
required: true,
});

View File

@@ -59,10 +59,10 @@ const showInputs = ref<boolean[]>([]);
watch(
showInputs,
(newValues) => {
// 当状态为 true 时
// 当状态为 true 时, 自动聚焦
newValues.forEach((value, index) => {
if (value) {
// 当显示状态从 false 变为 true 时
// 当显示状态从 false 变为 true 时, 自动聚焦
nextTick(() => {
inputRefs.value[index]?.focus();
});
@@ -137,7 +137,7 @@ function deleteCondition(index: number) {
// 移动节点
function moveNode(index: number, to: number) {
// -1 :向左 1向右
// -1 :向左 1 向右
if (
currentNode.value.conditionNodes &&
currentNode.value.conditionNodes[index]

View File

@@ -64,10 +64,10 @@ const showInputs = ref<boolean[]>([]);
watch(
showInputs,
(newValues) => {
// 当状态为 true 时
// 当状态为 true 时, 自动聚焦
newValues.forEach((value, index) => {
if (value) {
// 当显示状态从 false 变为 true 时
// 当显示状态从 false 变为 true 时, 自动聚焦
nextTick(() => {
inputRefs.value[index]?.focus();
});
@@ -141,7 +141,7 @@ function deleteCondition(index: number) {
// 移动节点
function moveNode(index: number, to: number) {
// -1 :向左 1向右
// -1 :向左 1 向右
if (
currentNode.value.conditionNodes &&
currentNode.value.conditionNodes[index]

View File

@@ -30,7 +30,7 @@ const [Modal, modalApi] = useVbenModal({
try {
const data = modalApi.getData<any[]>();
// 填充列表数据
await gridApi.setGridOptions({ data });
gridApi.setGridOptions({ data });
} finally {
modalApi.unlock();
}

View File

@@ -33,7 +33,7 @@ const [Modal, modalApi] = useVbenModal({
try {
const data = modalApi.getData<any[]>();
// 填充列表数据
await gridApi.setGridOptions({ data });
gridApi.setGridOptions({ data });
} finally {
modalApi.unlock();
}

View File

@@ -71,7 +71,7 @@ function recursiveFindParentNode(
}
</script>
<template>
<!-- 发起人节<EFBFBD>?-->
<!-- 发起人节 -->
<StartUserNode
v-if="currentNode && currentNode.type === BpmNodeTypeEnum.START_USER_NODE"
:flow-node="currentNode"
@@ -87,7 +87,7 @@ function recursiveFindParentNode(
@update:flow-node="handleModelValueUpdate"
@find-parent-node="findParentNode"
/>
<!-- 抄送节<EFBFBD>?-->
<!-- 抄送节-->
<CopyTaskNode
v-if="currentNode && currentNode.type === BpmNodeTypeEnum.COPY_TASK_NODE"
:flow-node="currentNode"
@@ -120,7 +120,7 @@ function recursiveFindParentNode(
@update:model-value="handleModelValueUpdate"
@find-parent-node="findParentNode"
/>
<!-- 延迟器节<EFBFBD>?-->
<!-- 延迟器节-->
<DelayTimerNode
v-if="currentNode && currentNode.type === BpmNodeTypeEnum.DELAY_TIMER_NODE"
:flow-node="currentNode"
@@ -134,13 +134,13 @@ function recursiveFindParentNode(
:flow-node="currentNode"
@update:flow-node="handleModelValueUpdate"
/>
<!-- 触发器节<EFBFBD>?-->
<!-- 触发器节-->
<TriggerNode
v-if="currentNode && currentNode.type === BpmNodeTypeEnum.TRIGGER_NODE"
:flow-node="currentNode"
@update:flow-node="handleModelValueUpdate"
/>
<!-- 子流程节<EFBFBD>?-->
<!-- 子流程节-->
<ChildProcessNode
v-if="
currentNode && currentNode.type === BpmNodeTypeEnum.CHILD_PROCESS_NODE

View File

@@ -263,6 +263,7 @@ const saveLoading = ref<boolean>(false);
/** 保存操作 */
async function handleSave() {
try {
saveLoading.value = true;
// 保存前校验所有步骤的数据
const result = await validateAllSteps();
if (!result) {
@@ -273,7 +274,7 @@ async function handleSave() {
const modelData = {
...formData.value,
};
saveLoading.value = true;
switch (actionType) {
case 'copy': {
// 情况三:复制场景
@@ -323,11 +324,10 @@ async function handleDeploy() {
if (!formData.value.id) {
await confirm('是否确认发布该流程?');
}
deployLoading.value = true;
// 1.2 校验所有步骤
await validateAllSteps();
deployLoading.value = true;
// 2.1 更新表单数据
const modelData = {
...formData.value,

View File

@@ -8,6 +8,8 @@ import { inject, onBeforeUnmount, provide, ref, shallowRef, watch } from 'vue';
import { ContentWrap } from '@vben/common-ui';
import { BpmModelFormType } from '@vben/constants';
import { ElMessage } from 'element-plus';
import { getForm } from '#/api/bpm/form';
import {
MyProcessDesigner,
@@ -47,7 +49,6 @@ const controlForm = ref({
headerButtonSize: 'mini',
additionalModel: [CustomContentPadProvider, CustomPaletteProvider],
});
const model = ref<BpmModelApi.Model>(); // 流程模型的信息
/** 初始化 modeler */
@@ -63,7 +64,7 @@ const save = async (bpmnXml: string) => {
emit('success', bpmnXml);
} catch (error) {
console.error('保存失败:', error);
// ElMessage.error('保存失败');
ElMessage.error('保存失败');
}
};

View File

@@ -30,6 +30,7 @@ import {
} from 'element-plus';
import { getForm } from '#/api/bpm/form';
// TODO @jason这里要迁移下么
// import {
// HttpRequestSetting,
// parseFormFields,

View File

@@ -185,6 +185,7 @@ onMounted(() => {
<template>
<Page auto-content-height>
<!-- TODO @jason这里交互可以做成类似 vue3 + element-plus 那个一样滚动切换分类哈对标钉钉飞书哈 -->
<!-- 第一步通过流程定义的列表选择对应的流程 -->
<template v-if="!selectProcessDefinition">
<ElCard

View File

@@ -223,8 +223,8 @@ watch(
const loading = ref(false);
/** 初始化 */
onMounted(async () => {
loading.value = true;
try {
loading.value = true;
await getDetail();
// 获得用户列表
userOptions.value = await getSimpleUserList();

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
// TODO @jason这个貌似暂时还没迁移的样子
// import { MyProcessViewer } from '#/views/bpm/components/bpmn-process-designer/package';
defineOptions({ name: 'ProcessInstanceBpmnViewer' });

View File

@@ -275,6 +275,7 @@ async function openPopover(type: string) {
}
}
Object.keys(popOverVisible.value).forEach((item) => {
// TODO @jason这里是不是保持和 antd 一致?
popOverVisible.value[item] = item === type;
});
}
@@ -704,6 +705,8 @@ function handleSignFinish(url: string) {
approveFormRef.value?.validateField('signPicUrl');
}
// TODO @jasonhandlePopoverVisible 需要要有么?
defineExpose({ loadTodoTask });
</script>
<template>
@@ -725,9 +728,9 @@ defineExpose({ loadTodoTask });
<template #reference>
<ElButton plain type="primary" @click="openPopover('approve')">
<IconifyIcon icon="lucide:check" />
<span class="ml-1">{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.APPROVE)
}}</span>
<span class="ml-1">
{{ getButtonDisplayName(BpmTaskOperationButtonTypeEnum.APPROVE) }}
</span>
</ElButton>
</template>
<!-- 办理表单 -->
@@ -979,6 +982,7 @@ defineExpose({ loadTodoTask });
label-width="100px"
>
<ElFormItem label="新审批人" prop="assigneeUserId">
<!-- TODO @jason是不是用 unocss 哈antd 和 ele 都要改下 -->
<ElSelect
v-model="transferForm.assigneeUserId"
clearable
@@ -1040,9 +1044,11 @@ defineExpose({ loadTodoTask });
<template #reference>
<ElButton plain @click="openPopover('delegate')">
<IconifyIcon :size="14" icon="icon-park-outline:user-positioning" />
<span class="ml-1">{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.DELEGATE)
}}</span>
<span class="ml-1">
{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.DELEGATE)
}}
</span>
</ElButton>
</template>
<div class="flex flex-1 flex-col px-5 pt-5" v-loading="formLoading">
@@ -1116,9 +1122,11 @@ defineExpose({ loadTodoTask });
<template #reference>
<ElButton plain @click="openPopover('addSign')">
<IconifyIcon :size="14" icon="icon-park-outline:plus" />
<span class="ml-1">{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.ADD_SIGN)
}}</span>
<span class="ml-1">
{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.ADD_SIGN)
}}
</span>
</ElButton>
</template>
<div class="flex flex-1 flex-col px-5 pt-5" v-loading="formLoading">
@@ -1272,9 +1280,9 @@ defineExpose({ loadTodoTask });
<template #reference>
<ElButton plain @click="openPopover('return')">
<IconifyIcon :size="14" icon="lucide:arrow-left" />
<span class="ml-1">{{
getButtonDisplayName(BpmTaskOperationButtonTypeEnum.RETURN)
}}</span>
<span class="ml-1">
{{ getButtonDisplayName(BpmTaskOperationButtonTypeEnum.RETURN) }}
</span>
</ElButton>
</template>
<div class="flex flex-1 flex-col px-5 pt-5" v-loading="formLoading">

View File

@@ -54,7 +54,6 @@ const [Modal, modalApi] = useVbenModal({
</ElButton>
</ElTooltip>
</div>
<Vue3Signature
class="h-full flex-1 border border-solid border-gray-300"
ref="signature"

View File

@@ -86,6 +86,8 @@ function useGridColumns(): VxeTableGridOptions['columns'] {
];
}
// TODO @jason是不是要 const formRef = ref<formCreate>();
const formRef = ref();
const taskForm = ref<TaskForm>({
rule: [],
@@ -187,6 +189,7 @@ defineExpose({
</Grid>
</div>
<Modal class="w-3/5">
<!-- TODO @jason是不是 antd ele 保持统一 -->
<FormCreate
ref="formRef"
v-model="taskForm.value"