import axios, { isAxiosError, type AxiosRequestConfig, type AxiosResponse, } from "axios"; import { withAdminAuthHeader } from "@/lib/admin-auth"; import { withAdminLocaleHeaders } from "@/lib/admin-locale"; import { LotteryApiBizError, LotteryApiEnvelopeError } from "@/types/api/errors"; import { isApiEnvelope } from "@/types/api/envelope"; const baseURL = process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL?.trim(); /** 是否已配置后台 API 根地址(客户端/服务端均可用 `NEXT_PUBLIC_*`) */ export function hasLotteryAdminApiBaseUrl(): boolean { return baseURL !== undefined && baseURL !== ""; } export const adminHttp = axios.create({ baseURL: baseURL && baseURL !== "" ? baseURL : undefined, timeout: 30_000, headers: { Accept: "application/json" }, }); export function unwrapData(payload: unknown): T { if (!isApiEnvelope(payload)) { throw new LotteryApiEnvelopeError(); } if (payload.code !== 0) { throw new LotteryApiBizError(payload.msg, payload.code, payload.data); } return payload.data as T; } export function unwrapResponse(res: AxiosResponse): T { return unwrapData(res.data); } /** 登录/验证码等:**不**附加 `Authorization`。 */ export async function publicAdminRequest( config: AxiosRequestConfig, ): Promise { try { const res = await adminHttp.request( withAdminLocaleHeaders(config), ); return unwrapResponse(res); } catch (err: unknown) { if (isAxiosError(err) && err.response?.data !== undefined) { const body = err.response.data; if (isApiEnvelope(body) && body.code !== 0) { throw new LotteryApiBizError(body.msg, body.code, body.data); } } throw err; } } export async function request(config: AxiosRequestConfig): Promise { const merged = withAdminAuthHeader(withAdminLocaleHeaders(config)); try { const res = await adminHttp.request(merged); return unwrapResponse(res); } catch (err: unknown) { if (isAxiosError(err) && err.response?.data !== undefined) { const body = err.response.data; if (isApiEnvelope(body) && body.code !== 0) { throw new LotteryApiBizError(body.msg, body.code, body.data); } } throw err; } } export const adminRequest = { request, get: (url: string, config?: Omit) => request({ ...config, url, method: "GET" }), delete: (url: string, config?: Omit) => request({ ...config, url, method: "DELETE" }), post: ( url: string, data?: unknown, config?: Omit, ) => request({ ...config, url, method: "POST", data }), patch: ( url: string, data?: unknown, config?: Omit, ) => request({ ...config, url, method: "PATCH", data }), put: ( url: string, data?: unknown, config?: Omit, ) => request({ ...config, url, method: "PUT", data }), };