diff --git a/apps/web-antd/src/api/bpm/form/index.ts b/apps/web-antd/src/api/bpm/form/index.ts index 0789071b2..99c1299e9 100644 --- a/apps/web-antd/src/api/bpm/form/index.ts +++ b/apps/web-antd/src/api/bpm/form/index.ts @@ -5,7 +5,7 @@ import { requestClient } from '#/api/request'; export namespace BpmFormApi { /** 流程表单 */ export interface Form { - id?: number | undefined; + id?: number; name: string; conf: string; fields: string[]; @@ -23,7 +23,7 @@ export async function getFormPage(params: PageParam) { } /** 获取表单详情 */ -export async function getFormDetail(id: number) { +export async function getForm(id: number) { return requestClient.get(`/bpm/form/get?id=${id}`); } diff --git a/apps/web-antd/src/api/bpm/model/index.ts b/apps/web-antd/src/api/bpm/model/index.ts index 443b85c5e..cd2afbc84 100644 --- a/apps/web-antd/src/api/bpm/model/index.ts +++ b/apps/web-antd/src/api/bpm/model/index.ts @@ -52,7 +52,7 @@ export interface ModelCategoryInfo { } /** 获取流程模型列表 */ -export async function getModelList(name: string | undefined) { +export async function getModelList(name?: string) { return requestClient.get('/bpm/model/list', { params: { name }, }); diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/child-process-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/child-process-node-config.vue index 012e4ac7a..25557024f 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/child-process-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/child-process-node-config.vue @@ -27,7 +27,7 @@ import { Switch, } from 'ant-design-vue'; -import { getFormDetail } from '#/api/bpm/form'; +import { getForm } from '#/api/bpm/form'; import { getModelList } from '#/api/bpm/model'; import { @@ -354,7 +354,7 @@ const loadFormInfo = async () => { ); if (!childInfo) return; - const formInfo = await getFormDetail(childInfo.formId); + const formInfo = await getForm(childInfo.formId); childFormFieldOptions.value = []; if (formInfo.fields) { formInfo.fields.forEach((fieldStr: string) => { diff --git a/apps/web-antd/src/components/simple-process-design/components/simple-process-designer.vue b/apps/web-antd/src/components/simple-process-design/components/simple-process-designer.vue index 22b4978bf..659f0a332 100644 --- a/apps/web-antd/src/components/simple-process-design/components/simple-process-designer.vue +++ b/apps/web-antd/src/components/simple-process-design/components/simple-process-designer.vue @@ -17,7 +17,7 @@ import { handleTree } from '@vben/utils'; import { Button } from 'ant-design-vue'; -import { getFormDetail } from '#/api/bpm/form'; +import { getForm } from '#/api/bpm/form'; import { getUserGroupSimpleList } from '#/api/bpm/userGroup'; import { getSimpleDeptList } from '#/api/system/dept'; import { getSimplePostList } from '#/api/system/post'; @@ -82,7 +82,7 @@ watch( () => props.modelFormId, async (newVal) => { if (newVal) { - const form = await getFormDetail(newVal); + const form = await getForm(newVal); formFields.value = form?.fields; } else { // 如果 modelFormId 为空,清空表单字段 diff --git a/apps/web-antd/src/router/routes/modules/bpm.ts b/apps/web-antd/src/router/routes/modules/bpm.ts index 21abaabe5..05e0e5664 100644 --- a/apps/web-antd/src/router/routes/modules/bpm.ts +++ b/apps/web-antd/src/router/routes/modules/bpm.ts @@ -51,7 +51,7 @@ const routes: RouteRecordRaw[] = [ name: 'BpmFormEditor', component: () => import('#/views/bpm/form/designer/index.vue'), meta: { - title: '编辑流程表单', + title: '设计流程表单', activePath: '/bpm/manager/form', }, props: (route) => { diff --git a/apps/web-antd/src/views/bpm/form/data.ts b/apps/web-antd/src/views/bpm/form/data.ts index 8235398dc..20ed60414 100644 --- a/apps/web-antd/src/views/bpm/form/data.ts +++ b/apps/web-antd/src/views/bpm/form/data.ts @@ -1,52 +1,7 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; -import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; -import { getDictOptions } from '@vben/hooks'; - -import { z } from '#/adapter/form'; - -/** 新增/修改的表单 */ -export function useFormSchema(): VbenFormSchema[] { - return [ - { - fieldName: 'id', - component: 'Input', - dependencies: { - triggerFields: [''], - show: () => false, - }, - }, - { - fieldName: 'name', - label: '表单名称', - component: 'Input', - componentProps: { - placeholder: '请输入表单名称', - }, - rules: 'required', - }, - { - fieldName: 'status', - label: '状态', - component: 'RadioGroup', - componentProps: { - options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), - buttonStyle: 'solid', - optionType: 'button', - }, - rules: z.number().default(CommonStatusEnum.ENABLE), - }, - { - fieldName: 'remark', - label: '备注', - component: 'Textarea', - componentProps: { - placeholder: '请输入备注', - }, - }, - ]; -} +import { DICT_TYPE } from '@vben/constants'; /** 列表的搜索表单 */ export function useGridFormSchema(): VbenFormSchema[] { diff --git a/apps/web-antd/src/views/bpm/form/designer/data.ts b/apps/web-antd/src/views/bpm/form/designer/data.ts new file mode 100644 index 000000000..36a993ca7 --- /dev/null +++ b/apps/web-antd/src/views/bpm/form/designer/data.ts @@ -0,0 +1,48 @@ +import type { VbenFormSchema } from '#/adapter/form'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '表单名称', + component: 'Input', + componentProps: { + placeholder: '请输入表单名称', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, + }, + ]; +} diff --git a/apps/web-antd/src/views/bpm/form/designer/index.vue b/apps/web-antd/src/views/bpm/form/designer/index.vue index 3b3f1bdc2..266fe51e6 100644 --- a/apps/web-antd/src/views/bpm/form/designer/index.vue +++ b/apps/web-antd/src/views/bpm/form/designer/index.vue @@ -2,18 +2,20 @@ import { computed, onMounted, ref } from 'vue'; import { Page, useVbenModal } from '@vben/common-ui'; +import { useTabs } from '@vben/hooks'; import { IconifyIcon } from '@vben/icons'; import FcDesigner from '@form-create/antd-designer'; -import { Button, message } from 'ant-design-vue'; +import { Button, message, Spin } from 'ant-design-vue'; -import { getFormDetail } from '#/api/bpm/form'; +import { getForm } from '#/api/bpm/form'; import { setConfAndFields, useFormCreateDesigner, } from '#/components/form-create'; import { router } from '#/router'; -import Form from '#/views/bpm/form/modules/form.vue'; + +import Form from './modules/form.vue'; defineOptions({ name: 'BpmFormEditor' }); @@ -23,17 +25,16 @@ const props = defineProps<{ type: 'copy' | 'create' | 'edit'; }>(); -/** 流程表单详情 */ +const loading = ref(false); +const tabs = useTabs(); const flowFormConfig = ref(); +const designerRef = ref>(); const [FormModal, formModalApi] = useVbenModal({ connectedComponent: Form, destroyOnClose: true, }); -const designerRef = ref>(); - -/** 表单设计器配置 */ const designerConfig = ref({ switchType: [], // 是否可以切换组件类型,或者可以相互切换的字段 autoActive: true, // 是否自动选中拖入的组件 @@ -61,11 +62,11 @@ const designerConfig = ref({ showInputData: true, // 是否显示录入按钮 showDevice: true, // 是否显示多端适配选项 appendConfigData: [], // 定义渲染规则所需的formData -}); +}); // 表单设计器配置 useFormCreateDesigner(designerRef); // 表单设计器增强 -// 计算属性:获取当前需要加载的表单ID +/** 计算属性:获取当前需要加载的表单 ID */ const currentFormId = computed(() => { switch (props.type) { case 'copy': { @@ -81,28 +82,27 @@ const currentFormId = computed(() => { } }); -// 加载表单配置 +/** 加载表单配置 */ async function loadFormConfig(id: number) { + loading.value = true; try { - const formDetail = await getFormDetail(id); + const formDetail = await getForm(id); flowFormConfig.value = formDetail; if (designerRef.value) { setConfAndFields(designerRef, formDetail.conf, formDetail.fields); } - } catch { - message.error('加载表单配置失败'); + } finally { + loading.value = false; } } -// 初始化设计器 +/** 初始化设计器 */ async function initializeDesigner() { const id = currentFormId.value; - if (props.type === 'copy' && !id) { - message.error('复制ID不能为空'); + message.error('复制 ID 不能为空'); return; } - if (id) { await loadFormConfig(Number(id)); } @@ -120,15 +120,14 @@ function handleSave() { } /** 返回列表页 */ -function onBack() { +function handleBack() { + tabs.closeCurrentTab(); router.push({ - path: '/bpm/manager/form', - query: { - refresh: '1', - }, + name: 'BpmForm', }); } +/** 初始化 */ onMounted(() => { initializeDesigner(); }); @@ -136,19 +135,21 @@ onMounted(() => { diff --git a/apps/web-antd/src/views/bpm/form/modules/form.vue b/apps/web-antd/src/views/bpm/form/designer/modules/form.vue similarity index 93% rename from apps/web-antd/src/views/bpm/form/modules/form.vue rename to apps/web-antd/src/views/bpm/form/designer/modules/form.vue index 5ff14b201..42766c63d 100644 --- a/apps/web-antd/src/views/bpm/form/modules/form.vue +++ b/apps/web-antd/src/views/bpm/form/designer/modules/form.vue @@ -39,20 +39,18 @@ const [Form, formApi] = useVbenForm({ const [Modal, modalApi] = useVbenModal({ async onConfirm() { - // 表单验证 const { valid } = await formApi.validate(); - if (!valid) return; - - // 锁定模态框 + if (!valid) { + return; + } modalApi.lock(); + // 提交表单 try { // 获取表单数据 const data = (await formApi.getValues()) as BpmFormApi.Form; - // 编码表单配置和表单字段 data.conf = encodeConf(designerComponent); data.fields = encodeFields(designerComponent); - // 保存表单数据 if (formData.value?.id) { await (editorAction.value === 'copy' @@ -61,7 +59,7 @@ const [Modal, modalApi] = useVbenModal({ } else { await createForm(data); } - + // 关闭并提示 await modalApi.close(); emit('success'); message.success($t('ui.actionMessage.operationSuccess')); @@ -76,15 +74,16 @@ const [Modal, modalApi] = useVbenModal({ designerComponent.value = undefined; return; } - + // 加载数据 const data = modalApi.getData(); - if (!data) return; - + if (!data) { + return; + } + modalApi.lock(); // 设置表单设计器组件 designerComponent.value = data.designer; formData.value = data.formConfig; editorAction.value = data.action; - // 如果是复制,表单名称后缀添加 _copy ,id 置空 if (editorAction.value === 'copy' && formData.value) { formData.value = { @@ -93,8 +92,8 @@ const [Modal, modalApi] = useVbenModal({ id: undefined, }; } - try { + // 设置到 values if (formData.value) { await formApi.setValues(formData.value); } diff --git a/apps/web-antd/src/views/bpm/form/index.vue b/apps/web-antd/src/views/bpm/form/index.vue index fff4d2a8e..f3b9d26c8 100644 --- a/apps/web-antd/src/views/bpm/form/index.vue +++ b/apps/web-antd/src/views/bpm/form/index.vue @@ -2,8 +2,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { BpmFormApi } from '#/api/bpm/form'; -import { watch } from 'vue'; -import { useRoute } from 'vue-router'; +import { onActivated } from 'vue'; import { DocAlert, Page, useVbenModal } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -24,7 +23,7 @@ function handleRefresh() { gridApi.query(); } -/** 新增 */ +/** 新增表单 */ function handleCreate() { router.push({ name: 'BpmFormEditor', @@ -34,7 +33,7 @@ function handleCreate() { }); } -/** 编辑 */ +/** 编辑表单 */ function handleEdit(row: BpmFormApi.Form) { router.push({ name: 'BpmFormEditor', @@ -45,7 +44,7 @@ function handleEdit(row: BpmFormApi.Form) { }); } -/** 复制 */ +/** 复制表单 */ function handleCopy(row: BpmFormApi.Form) { router.push({ name: 'BpmFormEditor', @@ -56,35 +55,31 @@ function handleCopy(row: BpmFormApi.Form) { }); } -/** 删除 */ +/** 删除表单 */ async function handleDelete(row: BpmFormApi.Form) { const hideLoading = message.loading({ content: $t('ui.actionMessage.deleting', [row.name]), duration: 0, }); try { - await deleteForm(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + await deleteForm(row.id!); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); } } + +/** 查看表单详情 */ async function handleDetail(row: BpmFormApi.Form) { detailModalApi.setData(row).open(); } -/** 详情弹窗 */ const [DetailModal, detailModalApi] = useVbenModal({ connectedComponent: Detail, destroyOnClose: true, }); -/** 检测路由参数 */ -const route = useRoute(); - const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -106,26 +101,19 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, search: true, }, - cellConfig: { - height: 64, - }, } as VxeTableGridOptions, }); -watch( - () => route.query.refresh, - (val) => { - if (val === '1') { - handleRefresh(); - } - }, - { immediate: true }, -); +/** 激活时 */ +onActivated(() => { + handleRefresh(); +});