diff --git a/apps/web-antd/src/locales/langs/en-US/common.json b/apps/web-antd/src/locales/langs/en-US/common.json new file mode 100644 index 00000000..cdfabf4c --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/common.json @@ -0,0 +1,7 @@ +{ + "export": { + "title": "Export", + "loading": "Exporting...", + "canceled": "Export has been cancelled." + } +} diff --git a/apps/web-antd/src/locales/langs/en-US/pages.json b/apps/web-antd/src/locales/langs/en-US/pages.json index 901a75a1..ca0359ca 100644 --- a/apps/web-antd/src/locales/langs/en-US/pages.json +++ b/apps/web-antd/src/locales/langs/en-US/pages.json @@ -22,6 +22,7 @@ "tip": "Tip", "enable": "On", "disable": "Off", - "beforeCloseTip": "You have unsaved changes. Are you sure you want to exit?" + "beforeCloseTip": "You have unsaved changes. Are you sure you want to exit?", + "cancel": "Cancel" } } diff --git a/apps/web-antd/src/locales/langs/zh-CN/common.json b/apps/web-antd/src/locales/langs/zh-CN/common.json new file mode 100644 index 00000000..2577ab8b --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/common.json @@ -0,0 +1,7 @@ +{ + "export": { + "title": "导出", + "loading": "导出中...", + "canceled": "导出已取消" + } +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/pages.json b/apps/web-antd/src/locales/langs/zh-CN/pages.json index eab87798..c39978e2 100644 --- a/apps/web-antd/src/locales/langs/zh-CN/pages.json +++ b/apps/web-antd/src/locales/langs/zh-CN/pages.json @@ -22,6 +22,7 @@ "tip": "提示", "enable": "启用", "disable": "禁用", - "beforeCloseTip": "您有未保存的更改,确认要退出吗?" + "beforeCloseTip": "您有未保存的更改,确认要退出吗?", + "cancel": "取消" } } diff --git a/apps/web-antd/src/utils/file/export.tsx b/apps/web-antd/src/utils/file/export.tsx new file mode 100644 index 00000000..fbbdefb3 --- /dev/null +++ b/apps/web-antd/src/utils/file/export.tsx @@ -0,0 +1,76 @@ +import type { loginInfoExport } from '#/api/monitor/logininfo'; + +import { ref } from 'vue'; + +import { useRequest } from 'alova/client'; +import { Button } from 'antdv-next'; +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +import { downloadByData } from './download'; + +// TODO: 这里的泛型实在难写 且基本都是统一按格式 +export type ExportBlobApi = typeof loginInfoExport; + +export interface ExportBlobFuncOptions { + fileName: string; + data?: any; +} + +export function useBlobExport(api: ExportBlobApi) { + const exportLoading = ref(false); + + const { send, abort } = useRequest(api, { immediate: false }); + + async function exportBlob(options: ExportBlobFuncOptions) { + const { fileName, data } = options; + + const hide = window.message.loading({ + content: ( +
+ {$t('common.export.loading')} + +
+ ), + duration: 9999, + }); + + exportLoading.value = true; + try { + const blob = await send(data ?? {}); + downloadByData(blob, fileName); + } catch (error) { + console.error(error); + } finally { + hide(); + exportLoading.value = false; + } + } + + /** + * 构建导出文件名 放在这里的好处是可以做国际化文案 + * @param module 模块名称 + * @returns 导出文件名 + */ + function buildExportFileName(module: string, extension = 'xlsx') { + return `${module} ${$t('common.export.title')} - ${dayjs().valueOf()}.${extension}`; + } + + return { + exportBlob, + exportLoading, + buildExportFileName, + }; +} diff --git a/apps/web-antd/src/views/system/user/index.vue b/apps/web-antd/src/views/system/user/index.vue index d2d50aee..6b62ee2c 100644 --- a/apps/web-antd/src/views/system/user/index.vue +++ b/apps/web-antd/src/views/system/user/index.vue @@ -24,7 +24,7 @@ import { userStatusChange, } from '#/api/system/user'; import ApiSwitch from '#/components/global/api-switch.vue'; -import { commonDownloadExcel } from '#/utils/file/download'; +import { useBlobExport } from '#/utils/file/export'; import { columns, querySchema } from './data'; import DeptTree from './dept-tree.vue'; @@ -156,10 +156,14 @@ function handleMultiDelete() { }); } -function handleDownloadExcel() { - commonDownloadExcel(userExport, '用户管理', tableApi.formApi.form.values, { - fieldMappingTime: formOptions.fieldMappingTime, - }); +const { exportBlob, exportLoading, buildExportFileName } = + useBlobExport(userExport); +async function handleExport() { + // 构建表单请求参数 + const formValues = await tableApi.formApi.getValues(); + // 文件名 + const fileName = buildExportFileName('用户信息'); + exportBlob({ data: formValues, fileName }); } const [UserInfoModal, userInfoModalApi] = useVbenModal({ @@ -202,7 +206,6 @@ function handleMenuClick(key: string, row: any) { } async function handleChangeStatus(checked: boolean, row: User) { - console.log(checked); await userStatusChange({ userId: row.userId, status: checked ? EnableStatus.Enable : EnableStatus.Disable, @@ -224,7 +227,9 @@ async function handleChangeStatus(checked: boolean, row: User) { {{ $t('pages.common.export') }}