优化
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
import axios from 'axios'
|
||||
import { ApiResponseError, http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
|
||||
export type ExportTaskStatus = 'PENDING' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'EXPIRED'
|
||||
export type ExportTaskType = 'CUSTOMER_LIST' | string
|
||||
@@ -49,6 +50,45 @@ export interface CreatePlatformExportTaskRequest {
|
||||
}
|
||||
|
||||
const basePath = '/platform/v1/files/export-tasks'
|
||||
const downloadTimeoutMs = 10 * 60 * 1000
|
||||
const maxErrorEnvelopeBytes = 1024 * 1024
|
||||
|
||||
async function parseDownloadErrorBlob(blob: Blob, status?: number): Promise<ApiResponseError | null> {
|
||||
if (!blob.type.toLowerCase().includes('json')) return null
|
||||
|
||||
if (blob.size > maxErrorEnvelopeBytes) {
|
||||
return new ApiResponseError(
|
||||
'下载接口返回了超出限制的 JSON 响应',
|
||||
'INVALID_DOWNLOAD_RESPONSE',
|
||||
status,
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
const payload = JSON.parse(await blob.text()) as Partial<ApiEnvelope<unknown>>
|
||||
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
||||
return new ApiResponseError(
|
||||
'下载接口返回了无法识别的 JSON 响应',
|
||||
'INVALID_DOWNLOAD_RESPONSE',
|
||||
status,
|
||||
)
|
||||
}
|
||||
return new ApiResponseError(
|
||||
payload.code === '200' ? '下载接口未返回文件内容' : payload.message || '文件下载失败',
|
||||
payload.code === '200' ? 'INVALID_DOWNLOAD_RESPONSE' : payload.code || (status ? `HTTP_${status}` : 'DOWNLOAD_FAILED'),
|
||||
status,
|
||||
payload.data,
|
||||
payload.requestId,
|
||||
payload.traceId,
|
||||
)
|
||||
} catch {
|
||||
return new ApiResponseError(
|
||||
'下载接口返回了无法识别的 JSON 响应',
|
||||
'INVALID_DOWNLOAD_RESPONSE',
|
||||
status,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function createPlatformExportTask(payload: CreatePlatformExportTaskRequest) {
|
||||
const response = await http.post<ApiEnvelope<PlatformExportTask>, ApiEnvelope<PlatformExportTask>>(basePath, payload)
|
||||
@@ -69,8 +109,30 @@ export async function listPlatformExportTasks(query: PlatformExportTaskQuery) {
|
||||
}
|
||||
}
|
||||
|
||||
export function downloadPlatformExportTask(taskId: string) {
|
||||
return http.get<Blob, Blob>(`${basePath}/${encodeURIComponent(taskId)}/download`, { responseType: 'blob' })
|
||||
export async function getPlatformExportTask(taskId: string) {
|
||||
const response = await http.get<ApiEnvelope<PlatformExportTask>, ApiEnvelope<PlatformExportTask>>(
|
||||
`${basePath}/${encodeURIComponent(taskId)}`,
|
||||
)
|
||||
return unwrapApiResponse(response)
|
||||
}
|
||||
|
||||
export async function downloadPlatformExportTask(taskId: string) {
|
||||
try {
|
||||
const blob = await http.get<Blob, Blob>(`${basePath}/${encodeURIComponent(taskId)}/download`, {
|
||||
responseType: 'blob',
|
||||
// 导出文件上限 50 MB,不能继承普通接口的 15 秒超时,也不能无限等待半断开的连接。
|
||||
timeout: downloadTimeoutMs,
|
||||
})
|
||||
const responseError = await parseDownloadErrorBlob(blob, 200)
|
||||
if (responseError) throw responseError
|
||||
return blob
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error) && error.response?.data instanceof Blob) {
|
||||
const responseError = await parseDownloadErrorBlob(error.response.data, error.response.status)
|
||||
if (responseError) throw responseError
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function retryPlatformExportTask(taskId: string) {
|
||||
|
||||
Reference in New Issue
Block a user