二维码池批量上传与认证图片预览修复

- 后端新增批量创建二维码接口 POST /admin/chats/qrcodes/batch
- 前端二维码管理页支持多图拖拽批量上传
- 注册 qrcode 图片压缩场景(maxSide=2560, quality=0.95)
- 后端 normalizeScene 注册 qrcode scene
- 增强 AuthImage 组件支持 el-image 大图预览(previewSrcList)
- 修复 WithdrawalDetailDialog 提现凭证图片 401 问题
- 删除重复的 components/AuthImage.vue,统一使用共享组件
- 提交3剩余: 会话列表群类型图标、发布成功跳群、管理端路由等
This commit is contained in:
yml
2026-06-17 17:57:05 +08:00
parent 54f550b8be
commit 12f589f0df
20 changed files with 715 additions and 33 deletions
@@ -0,0 +1,95 @@
import { apiClient } from '@/shared/api/client'
import type { ApiResponse, PaginatedResult } from '@/shared/types/types'
export type QrCodeStatus = 'unused' | 'used' | 'disabled'
export interface ChatQrCode {
id: number
image_url: string
status: QrCodeStatus
conversation_id: number | null
used_at: string | null
expires_at: string | null
created_by: number
note: string
created_at: string
updated_at: string
}
export interface QrCodeStats {
unused_count: number
used_count: number
disabled_count: number
total_count: number
}
export interface QrCodeListQuery {
status?: QrCodeStatus
page?: number
limit?: number
}
export interface CreateQrCodePayload {
image_url: string
note?: string
expires_at?: string | null
}
export interface UpdateQrCodePayload {
note?: string
status?: QrCodeStatus
expires_at?: string | null
}
export async function fetchQrCodes(query: QrCodeListQuery = {}) {
const { data } = await apiClient.get<ApiResponse<PaginatedResult<ChatQrCode>>>(
'/admin/chats/qrcodes',
{
params: { status: query.status || undefined, page: query.page || 1, limit: query.limit || 20 },
silent: true,
}
)
// 后端返回 { data: [...], pagination: { total, page, limit } },适配为 PaginatedResult
const resp = data.data as unknown as {
data: ChatQrCode[]
pagination: { total: number; page: number; limit: number }
}
return {
items: resp.data,
total: resp.pagination.total,
page: resp.pagination.page,
page_size: resp.pagination.limit,
} as PaginatedResult<ChatQrCode>
}
export async function fetchQrCodeStats() {
const { data } = await apiClient.get<ApiResponse<QrCodeStats>>('/admin/chats/qrcodes/stats', {
silent: true,
})
return data.data
}
export async function createQrCode(payload: CreateQrCodePayload) {
const { data } = await apiClient.post<ApiResponse<ChatQrCode>>('/admin/chats/qrcodes', payload)
return data.data
}
export async function batchCreateQrCodes(items: CreateQrCodePayload[]) {
const { data } = await apiClient.post<ApiResponse<ChatQrCode[]>>('/admin/chats/qrcodes/batch', {
items,
})
return data.data
}
export async function updateQrCode(id: number, payload: UpdateQrCodePayload) {
const { data } = await apiClient.patch<ApiResponse<ChatQrCode>>(
`/admin/chats/qrcodes/${id}`,
payload
)
return data.data
}
export async function deleteQrCode(id: number) {
const { data } = await apiClient.delete<ApiResponse<null>>(`/admin/chats/qrcodes/${id}`)
return data.data
}