From 5a5d2f17da8c2436803ceb891df16deb1ffa5bb8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 27 Dec 2025 12:49:14 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90bpm=E3=80=91=E3=80=90antd?= =?UTF-8?q?/ele=E3=80=91=E4=B8=9A=E5=8A=A1=E8=A1=A8=E5=8D=95=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=87=8D=E6=96=B0=E5=8F=91=E8=B5=B7=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/api/bpm/model/index.ts | 1 + .../src/views/bpm/oa/leave/create.vue | 39 ++++++++++++++++++- apps/web-antd/src/views/bpm/oa/leave/data.ts | 2 +- .../web-antd/src/views/bpm/oa/leave/index.vue | 19 ++++++++- .../src/views/bpm/processInstance/index.vue | 33 +++++++++++----- apps/web-ele/src/api/bpm/model/index.ts | 1 + .../src/views/bpm/processInstance/index.vue | 33 +++++++++++----- 7 files changed, 106 insertions(+), 22 deletions(-) diff --git a/apps/web-antd/src/api/bpm/model/index.ts b/apps/web-antd/src/api/bpm/model/index.ts index 545a73c03..e0c033a44 100644 --- a/apps/web-antd/src/api/bpm/model/index.ts +++ b/apps/web-antd/src/api/bpm/model/index.ts @@ -30,6 +30,7 @@ export namespace BpmModelApi { deploymentTime: number; suspensionState: number; formType?: number; + formCustomCreatePath?: string; formCustomViewPath?: string; formFields?: string[]; } diff --git a/apps/web-antd/src/views/bpm/oa/leave/create.vue b/apps/web-antd/src/views/bpm/oa/leave/create.vue index 19917d107..fd7a11105 100644 --- a/apps/web-antd/src/views/bpm/oa/leave/create.vue +++ b/apps/web-antd/src/views/bpm/oa/leave/create.vue @@ -3,6 +3,7 @@ import type { BpmOALeaveApi } from '#/api/bpm/oa/leave'; import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance'; import { computed, onMounted, ref, watch } from 'vue'; +import { useRoute } from 'vue-router'; import { confirm, Page, useVbenForm } from '@vben/common-ui'; import { BpmCandidateStrategyEnum, BpmNodeIdEnum } from '@vben/constants'; @@ -13,7 +14,7 @@ import { Button, Card, message, Space } from 'ant-design-vue'; import dayjs from 'dayjs'; import { getProcessDefinition } from '#/api/bpm/definition'; -import { createLeave, updateLeave } from '#/api/bpm/oa/leave'; +import { createLeave, getLeave, updateLeave } from '#/api/bpm/oa/leave'; import { getApprovalDetail as getApprovalDetailApi } from '#/api/bpm/processInstance'; import { $t } from '#/locales'; import { router } from '#/router'; @@ -22,6 +23,7 @@ import ProcessInstanceTimeline from '#/views/bpm/processInstance/detail/modules/ import { useFormSchema } from './data'; const { closeCurrentTab } = useTabs(); +const { query } = useRoute(); const formLoading = ref(false); // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 @@ -35,7 +37,7 @@ const processDefinitionId = ref(''); const formData = ref(); const getTitle = computed(() => { return formData.value?.id - ? $t('ui.actionTitle.edit', ['请假']) + ? '重新发起请假' : $t('ui.actionTitle.create', ['请假']); }); @@ -157,6 +159,34 @@ function selectUserConfirm(id: string, userList: any[]) { startUserSelectAssignees.value[id] = userList?.map((item: any) => item.id); } +/** 获取请假数据,用于重新发起时自动填充 */ +async function getDetail(id: number) { + try { + formLoading.value = true; + const data = await getLeave(id); + if (!data) { + message.error('重新发起请假失败,原因:请假数据不存在'); + return; + } + formData.value = { + ...formData.value, + id: data.id, + type: data.type, + reason: data.reason, + startTime: data.startTime, + endTime: data.endTime, + } as BpmOALeaveApi.Leave; + await formApi.setValues({ + type: data.type, + reason: data.reason, + startTime: data.startTime, + endTime: data.endTime, + }); + } finally { + formLoading.value = false; + } +} + /** 审批相关:预测流程节点会因为输入的参数值而产生新的预测结果值,所以需重新预测一次, formData.value可改成实际业务中的特定字段 */ watch( formData.value as object, @@ -190,6 +220,11 @@ onMounted(async () => { processDefinitionId.value = processDefinitionDetail.id; startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks; + // 如果是重新发起,则加载请假数据 + if (query.id) { + await getDetail(Number(query.id)); + } + await getApprovalDetail(); }); diff --git a/apps/web-antd/src/views/bpm/oa/leave/data.ts b/apps/web-antd/src/views/bpm/oa/leave/data.ts index 79140ef2f..9570f422d 100644 --- a/apps/web-antd/src/views/bpm/oa/leave/data.ts +++ b/apps/web-antd/src/views/bpm/oa/leave/data.ts @@ -168,7 +168,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 240, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/bpm/oa/leave/index.vue b/apps/web-antd/src/views/bpm/oa/leave/index.vue index fae7f7c4a..70748c819 100644 --- a/apps/web-antd/src/views/bpm/oa/leave/index.vue +++ b/apps/web-antd/src/views/bpm/oa/leave/index.vue @@ -33,6 +33,16 @@ function handleCreate() { }); } +/** 重新发起请假 */ +function handleReCreate(row: BpmOALeaveApi.Leave) { + router.push({ + name: 'OALeaveCreate', + query: { + id: row.id, + }, + }); +} + /** 取消请假 */ function handleCancel(row: BpmOALeaveApi.Leave) { prompt({ @@ -161,9 +171,16 @@ const [Grid, gridApi] = useVbenVxeGrid({ type: 'link', danger: true, icon: ACTION_ICON.DELETE, - ifShow: row.result === BpmProcessInstanceStatus.RUNNING, + ifShow: row.status === BpmProcessInstanceStatus.RUNNING, onClick: handleCancel.bind(null, row), }, + { + label: '重新发起', + type: 'link', + icon: ACTION_ICON.ADD, + ifShow: row.status !== BpmProcessInstanceStatus.RUNNING, + onClick: handleReCreate.bind(null, row), + }, ]" /> diff --git a/apps/web-antd/src/views/bpm/processInstance/index.vue b/apps/web-antd/src/views/bpm/processInstance/index.vue index 44c05463d..ddb721467 100644 --- a/apps/web-antd/src/views/bpm/processInstance/index.vue +++ b/apps/web-antd/src/views/bpm/processInstance/index.vue @@ -5,7 +5,11 @@ import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance'; import { h } from 'vue'; import { DocAlert, Page, prompt } from '@vben/common-ui'; -import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants'; +import { + BpmModelFormType, + BpmProcessInstanceStatus, + DICT_TYPE, +} from '@vben/constants'; import { Button, message, Textarea } from 'ant-design-vue'; @@ -37,23 +41,34 @@ function handleDetail(row: BpmProcessInstanceApi.ProcessInstance) { } /** 重新发起流程 */ -async function handleCreate(row: BpmProcessInstanceApi.ProcessInstance) { - // 如果是【业务表单】,不支持重新发起 +async function handleCreate(row?: BpmProcessInstanceApi.ProcessInstance) { if (row?.id) { const processDefinitionDetail = await getProcessDefinition( row.processDefinitionId, ); - if (processDefinitionDetail.formType === 20) { - message.error( - '重新发起流程失败,原因:该流程使用业务表单,不支持重新发起', - ); + if (processDefinitionDetail?.formType === BpmModelFormType.CUSTOM) { + if (!processDefinitionDetail.formCustomCreatePath) { + message.error('未配置业务表单的提交路由,无法重新发起'); + return; + } + await router.push({ + path: processDefinitionDetail.formCustomCreatePath, + query: { + id: row.businessKey, + }, + }); + return; + } else if (processDefinitionDetail?.formType === BpmModelFormType.NORMAL) { + await router.push({ + name: 'BpmProcessInstanceCreate', + query: { processInstanceId: row.id }, + }); return; } } - // 跳转发起流程界面 await router.push({ name: 'BpmProcessInstanceCreate', - query: { processInstanceId: row?.id }, + query: row?.id ? { processInstanceId: row.id } : {}, }); } diff --git a/apps/web-ele/src/api/bpm/model/index.ts b/apps/web-ele/src/api/bpm/model/index.ts index 545a73c03..e0c033a44 100644 --- a/apps/web-ele/src/api/bpm/model/index.ts +++ b/apps/web-ele/src/api/bpm/model/index.ts @@ -30,6 +30,7 @@ export namespace BpmModelApi { deploymentTime: number; suspensionState: number; formType?: number; + formCustomCreatePath?: string; formCustomViewPath?: string; formFields?: string[]; } diff --git a/apps/web-ele/src/views/bpm/processInstance/index.vue b/apps/web-ele/src/views/bpm/processInstance/index.vue index 52936bcbc..b4d85896d 100644 --- a/apps/web-ele/src/views/bpm/processInstance/index.vue +++ b/apps/web-ele/src/views/bpm/processInstance/index.vue @@ -5,7 +5,11 @@ import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance'; import { h } from 'vue'; import { DocAlert, Page, prompt } from '@vben/common-ui'; -import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants'; +import { + BpmModelFormType, + BpmProcessInstanceStatus, + DICT_TYPE, +} from '@vben/constants'; import { ElButton, ElInput, ElMessage } from 'element-plus'; @@ -37,23 +41,34 @@ function handleDetail(row: BpmProcessInstanceApi.ProcessInstance) { } /** 重新发起流程 */ -async function handleCreate(row: BpmProcessInstanceApi.ProcessInstance) { - // 如果是【业务表单】,不支持重新发起 +async function handleCreate(row?: BpmProcessInstanceApi.ProcessInstance) { if (row?.id) { const processDefinitionDetail = await getProcessDefinition( row.processDefinitionId, ); - if (processDefinitionDetail.formType === 20) { - ElMessage.error( - '重新发起流程失败,原因:该流程使用业务表单,不支持重新发起', - ); + if (processDefinitionDetail?.formType === BpmModelFormType.CUSTOM) { + if (!processDefinitionDetail.formCustomCreatePath) { + ElMessage.error('未配置业务表单的提交路由,无法重新发起'); + return; + } + await router.push({ + path: processDefinitionDetail.formCustomCreatePath, + query: { + id: row.businessKey, + }, + }); + return; + } else if (processDefinitionDetail?.formType === BpmModelFormType.NORMAL) { + await router.push({ + name: 'BpmProcessInstanceCreate', + query: { processInstanceId: row.id }, + }); return; } } - // 跳转发起流程界面 await router.push({ name: 'BpmProcessInstanceCreate', - query: { processInstanceId: row?.id }, + query: row?.id ? { processInstanceId: row.id } : {}, }); }