From 57a35f2f9d8b5ac26f8699af253093d5a5c8c39d Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 30 Oct 2026 20:03:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BC=9A=E5=91=98=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A2=9E=E5=8A=A0=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/member/user/index.ts | 35 ++ src/components/PreviewImage/index.vue | 10 +- .../user/components/UserExportDialog.vue | 501 ++++++++++++++++++ src/views/member/user/index.vue | 220 +++++++- tests/member-user-export.test.cjs | 315 +++++++++++ 5 files changed, 1057 insertions(+), 24 deletions(-) create mode 100644 src/views/member/user/components/UserExportDialog.vue create mode 100644 tests/member-user-export.test.cjs diff --git a/src/api/member/user/index.ts b/src/api/member/user/index.ts index 1dd933a8..4596b111 100644 --- a/src/api/member/user/index.ts +++ b/src/api/member/user/index.ts @@ -9,6 +9,9 @@ export interface UserVO { loginIp: string mark: string mobile: string + wechatNum?: string | null + wechatQrCode?: string | null + addressAreaNames?: string[] name: string | undefined nickname: string | undefined registerIp: string @@ -27,6 +30,38 @@ export const getUserPage = async (params) => { return await request.get({ url: `/member/user/page`, params }) } +export interface UserExportProgress { + taskId: string + status: 'WAITING' | 'RUNNING' | 'SUCCESS' | 'FAILURE' + total: number + processed: number + progress: number + message: string + fileName: string + existingTask: boolean + retentionHours: number +} + +// 使用与列表相同的查询参数序列化方式,时间范围、标签数组等保持一致。 +export const exportUsers = (params: Record) => { + return request.post({ url: '/member/user/export-async', params }) +} + +export const getUserExportProgress = (taskId: string) => { + return request.get({ + url: '/member/user/export-progress', + params: { taskId } + }) +} + +export const downloadUserExport = (taskId: string) => { + return request.download({ + url: '/member/user/export-download', + params: { taskId }, + timeout: 300000 + }) +} + // 查询会员用户详情 export const getUser = async (id: number) => { return await request.get({ url: `/member/user/get?id=` + id }) diff --git a/src/components/PreviewImage/index.vue b/src/components/PreviewImage/index.vue index 13f7a370..3caaf7da 100644 --- a/src/components/PreviewImage/index.vue +++ b/src/components/PreviewImage/index.vue @@ -3,6 +3,8 @@ type Props = { src?: string + alt?: string + fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' width?: string | number height?: string | number download?: boolean | string @@ -10,6 +12,7 @@ type Props = { } const props = withDefaults(defineProps(), { + fit: 'cover', width: 50, height: 50, download: false, @@ -61,7 +64,8 @@ function dispatchUrl(url?: string) {