| | |
| | | import { Page, useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { downloadFileFromBlobPart } from '#/packages/utils/src'; |
| | | |
| | | import { Button, message, Tag } from 'ant-design-vue'; |
| | | import { Button, message, Progress, Tag } from 'ant-design-vue'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | import { getDictLabel } from '#/packages/effects/hooks/src'; |
| | |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import ImportForm from './modules/import-form.vue'; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [ImportModal, importModalApi] = useVbenModal({ |
| | | connectedComponent: ImportForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | const exporting = ref(false); |
| | | const exportPercent = ref(0); |
| | | let exportTimer: ReturnType<typeof setInterval> | undefined; |
| | | |
| | | /** 模拟进度条:请求期间从 0 走到 90% */ |
| | | function startExportProgress() { |
| | | exportPercent.value = 0; |
| | | exportTimer = setInterval(() => { |
| | | if (exportPercent.value < 90) { |
| | | exportPercent.value = Math.min( |
| | | 90, |
| | | exportPercent.value + Math.random() * 12, |
| | | ); |
| | | } |
| | | }, 300); |
| | | } |
| | | |
| | | function stopExportProgress() { |
| | | if (exportTimer) { |
| | | clearInterval(exportTimer); |
| | | exportTimer = undefined; |
| | | } |
| | | } |
| | | |
| | | function delay(ms: number) { |
| | | return new Promise((resolve) => setTimeout(resolve, ms)); |
| | | } |
| | | |
| | | /** 导出员工 */ |
| | | async function handleExport() { |
| | | const data = await exportEmployee(await gridApi.formApi.getValues()); |
| | | downloadFileFromBlobPart({ fileName: '员工列表.xls', source: data }); |
| | | if (exporting.value) return; |
| | | exporting.value = true; |
| | | startExportProgress(); |
| | | try { |
| | | const data = await exportEmployee(await gridApi.formApi.getValues()); |
| | | // 完成:进度条走满后触发下载 |
| | | stopExportProgress(); |
| | | exportPercent.value = 100; |
| | | await delay(500); |
| | | downloadFileFromBlobPart({ fileName: '员工列表.xls', source: data }); |
| | | } finally { |
| | | stopExportProgress(); |
| | | exporting.value = false; |
| | | } |
| | | } |
| | | |
| | | /** 导入员工 */ |
| | | function handleImport() { |
| | | importModalApi.open(); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | |
| | | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <ImportModal @success="handleRefresh" /> |
| | | <FormModal @success="handleRefresh" /> |
| | | <Grid table-title="员工列表"> |
| | | <template #toolbar-tools> |
| | |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['hrm:employee:create'], |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: '导入', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.UPLOAD, |
| | | auth: ['hrm:employee:import'], |
| | | onClick: handleImport, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | |
| | | </template> |
| | | </Grid> |
| | | </Page> |
| | | <!-- 导出进度条遮罩 --> |
| | | <div |
| | | v-if="exporting" |
| | | class="fixed inset-0 z-[9999] flex items-center justify-center bg-black/40" |
| | | > |
| | | <div class="w-80 rounded-lg bg-white p-6 shadow-lg"> |
| | | <div class="mb-3 text-center text-sm text-gray-600"> |
| | | 正在导出员工列表... |
| | | </div> |
| | | <Progress :percent="exportPercent" status="active" /> |
| | | </div> |
| | | </div> |
| | | </template> |