| 123456789101112131415161718192021222324252627282930313233343536373839 |
- <template>
- <div class="p-4">
- <NCard title="待下载数据">
- <NDataTable :columns="columns" :data="jobs" :loading="loading" :row-key="(row: DataDownloadPackageJob) => row.id" />
- <div class="mt-4 flex justify-end"><NPagination v-model:page="page" :item-count="total" @update:page="load" /></div>
- </NCard>
- </div>
- </template>
- <script setup lang="tsx">
- import { NButton, NTag, type DataTableColumns } from 'naive-ui'
- import dayjs from 'dayjs'
- import { cancelDataDownloadPackage, deleteDataDownloadPackage, downloadDataDownloadPackage, getDataDownloadPackages, retryDataDownloadPackage } from '@/service/dataDownload'
- import type { DataDownloadPackageJob } from '@/service/dataDownload/interface'
- defineOptions({ name: 'DataDownloadPackages' })
- const message = useMessage()
- const jobs = ref<DataDownloadPackageJob[]>([])
- const loading = ref(false)
- const page = ref(1)
- const total = ref(0)
- const columns: DataTableColumns<DataDownloadPackageJob> = [
- { title: '文件名', key: 'filename', minWidth: 260 },
- { title: '状态', key: 'status', width: 130, render: row => <NTag type={row.status === 'complete' ? 'success' : row.status === 'failed' ? 'error' : 'warning'}>{row.status}</NTag> },
- { title: '进度', key: 'progress', width: 100, render: row => `${row.doneCount}/${row.totalCount}` },
- { title: '大小', key: 'size', width: 100, render: row => row.size ? `${(row.size / 1024 / 1024).toFixed(2)} MB` : '-' },
- { title: '创建时间', key: 'createdAt', width: 180, render: row => dayjs(row.createdAt).format('YYYY-MM-DD HH:mm:ss') },
- { title: '过期时间', key: 'expiresAt', width: 180, render: row => row.expiresAt ? dayjs(row.expiresAt).format('YYYY-MM-DD HH:mm:ss') : '-' },
- { title: '操作', key: 'action', width: 250, render: row => <div class="flex gap-2"><NButton size="small" type="primary" disabled={row.status !== 'complete'} onClick={() => downloadDataDownloadPackage(row.id)}>下载</NButton><NButton size="small" disabled={row.status !== 'failed'} onClick={() => retry(row)}>重试</NButton><NButton size="small" disabled={!['pending', 'running'].includes(row.status)} onClick={() => cancel(row)}>取消</NButton><NButton size="small" type="error" disabled={['pending', 'running', 'cancelling'].includes(row.status)} onClick={() => remove(row)}>删除</NButton></div> },
- ]
- async function load() { loading.value = true; try { const data = await getDataDownloadPackages(page.value, 20); jobs.value = data.items || []; total.value = data.total || 0 } finally { loading.value = false } }
- async function cancel(row: DataDownloadPackageJob) { await cancelDataDownloadPackage(row.id); message.success('已请求取消'); await load() }
- async function retry(row: DataDownloadPackageJob) { await retryDataDownloadPackage(row.id); message.success('已创建新的打包任务'); await load() }
- async function remove(row: DataDownloadPackageJob) { await deleteDataDownloadPackage(row.id); message.success('已删除 ZIP 及记录'); await load() }
- onMounted(load)
- let timer: number | undefined
- watch(jobs, value => { clearTimeout(timer); if (value.some(row => ['pending', 'running', 'cancelling'].includes(row.status))) timer = window.setTimeout(load, 5000) }, { deep: true })
- onBeforeUnmount(() => clearTimeout(timer))
- </script>
|