145 lines
3.9 KiB
TypeScript
145 lines
3.9 KiB
TypeScript
import type { ApiResponse } from "./client"
|
|
import { toast } from "@/components/ui/use-toast"
|
|
|
|
// 错误代码映射表
|
|
const errorMessages: Record<string, string> = {
|
|
// 用户相关错误
|
|
USER_NOT_FOUND: "用户不存在",
|
|
EMAIL_EXISTS: "该邮箱已被注册",
|
|
CANNOT_DELETE_ADMIN: "无法删除超级管理员用户",
|
|
|
|
// 角色相关错误
|
|
ROLE_NOT_FOUND: "角色不存在",
|
|
ROLE_EXISTS: "该角色名称已存在",
|
|
CANNOT_DELETE_SYSTEM_ROLE: "无法删除系统角色",
|
|
ROLE_IN_USE: "该角色正在被用户使用,无法删除",
|
|
|
|
// 服装相关错误
|
|
OUTFIT_NOT_FOUND: "服装不存在",
|
|
OUTFIT_ALREADY_PUBLISHED: "服装已发布,无法修改",
|
|
BATCH_NOT_FOUND: "批次不存在",
|
|
|
|
// 道具相关错误
|
|
PROP_NOT_FOUND: "道具不存在",
|
|
PROP_ALREADY_PUBLISHED: "道具已发布,无法修改",
|
|
|
|
// 歌曲相关错误
|
|
SONG_NOT_FOUND: "歌曲不存在",
|
|
SONG_ALREADY_PUBLISHED: "歌曲已发布,无法修改",
|
|
|
|
// 通用错误
|
|
NETWORK_ERROR: "网络错误,请检查网络连接",
|
|
SERVER_ERROR: "服务器错误,请稍后重试",
|
|
UNAUTHORIZED: "未授权,请重新登录",
|
|
FORBIDDEN: "无权限执行此操作",
|
|
}
|
|
|
|
// 处理API错误
|
|
export const handleApiError = (error: unknown): string => {
|
|
if (error instanceof Error) {
|
|
return error.message
|
|
}
|
|
return "发生未知错误,请重试"
|
|
}
|
|
|
|
// 创建API错误
|
|
export class ApiError extends Error {
|
|
status: number
|
|
|
|
constructor(message: string, status = 500) {
|
|
super(message)
|
|
this.name = "ApiError"
|
|
this.status = status
|
|
}
|
|
}
|
|
|
|
// 处理API响应
|
|
export const handleResponse = async <T>(response: Response)
|
|
: Promise<T> =>
|
|
{
|
|
if (!response.ok) {
|
|
const errorData = await response.json().catch(() => ({}))
|
|
throw new ApiError(errorData.message || `请求失败: ${response.status} ${response.statusText}`, response.status)
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
// 显示API错误提示
|
|
export function showApiError<T>(response: ApiResponse<T>, defaultMessage = "操作失败"): void {
|
|
const errorMessage = handleApiError(response, defaultMessage)
|
|
toast({
|
|
title: "错误",
|
|
description: errorMessage,
|
|
variant: "destructive",
|
|
})
|
|
}
|
|
|
|
// 处理API异常
|
|
export function handleApiException(error: unknown, defaultMessage = "操作失败"): string {
|
|
console.error("API Exception:", error)
|
|
|
|
if (error instanceof Error) {
|
|
if (error.message.includes("Network error")) {
|
|
return errorMessages["NETWORK_ERROR"]
|
|
}
|
|
return error.message
|
|
}
|
|
|
|
return defaultMessage
|
|
}
|
|
|
|
// 显示API异常提示
|
|
export function showApiException(error: unknown, defaultMessage = "操作失败"): void {
|
|
const errorMessage = handleApiException(error, defaultMessage)
|
|
toast({
|
|
title: "错误",
|
|
description: errorMessage,
|
|
variant: "destructive",
|
|
})
|
|
}
|
|
|
|
// 统一的API请求处理函数
|
|
export async function handleApiRequest<T>(
|
|
apiCall: () => Promise<ApiResponse<T>>,
|
|
options: {
|
|
successMessage?: string
|
|
errorMessage?: string
|
|
showSuccessToast?: boolean
|
|
showErrorToast?: boolean
|
|
} = {},
|
|
): Promise<{ success: boolean; data?: T; error?: string }> {
|
|
const {
|
|
successMessage = "操作成功",
|
|
errorMessage = "操作失败",
|
|
showSuccessToast = true,
|
|
showErrorToast = true,
|
|
} = options
|
|
|
|
try {
|
|
const response = await apiCall()
|
|
|
|
if (response.success) {
|
|
if (showSuccessToast) {
|
|
toast({
|
|
title: "成功",
|
|
description: successMessage,
|
|
})
|
|
}
|
|
return { success: true, data: response.data }
|
|
} else {
|
|
const error = handleApiError(response, errorMessage)
|
|
if (showErrorToast) {
|
|
showApiError(response, errorMessage)
|
|
}
|
|
return { success: false, error }
|
|
}
|
|
} catch (error) {
|
|
const errorMsg = handleApiException(error, errorMessage)
|
|
if (showErrorToast) {
|
|
showApiException(error, errorMessage)
|
|
}
|
|
return { success: false, error: errorMsg }
|
|
}
|
|
}
|