feat:初始化业务目录

This commit is contained in:
2026-05-09 10:36:20 +08:00
parent 881506655d
commit 56951c0383
60 changed files with 6955 additions and 184 deletions

92
src/lib/admin-http.ts Normal file
View File

@@ -0,0 +1,92 @@
import axios, {
isAxiosError,
type AxiosRequestConfig,
type AxiosResponse,
} from "axios";
import { withAdminAuthHeader } from "@/lib/admin-auth";
import { API_V1_PREFIX } from "@/lib/paths";
import { LotteryApiBizError, LotteryApiEnvelopeError } from "@/types/api/errors";
import { isApiEnvelope } from "@/types/api/envelope";
const baseURL = process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL?.trim();
export const adminHttp = axios.create({
baseURL: baseURL && baseURL !== "" ? baseURL : undefined,
timeout: 30_000,
headers: { Accept: "application/json" },
});
export function unwrapData<T>(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<T>(res: AxiosResponse<unknown>): T {
return unwrapData<T>(res.data);
}
export async function request<T>(config: AxiosRequestConfig): Promise<T> {
const merged = withAdminAuthHeader(config);
try {
const res = await adminHttp.request<unknown>(merged);
return unwrapResponse<T>(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: <T>(url: string, config?: Omit<AxiosRequestConfig, "url" | "method">) =>
request<T>({ ...config, url, method: "GET" }),
delete: <T>(url: string, config?: Omit<AxiosRequestConfig, "url" | "method">) =>
request<T>({ ...config, url, method: "DELETE" }),
post: <T>(
url: string,
data?: unknown,
config?: Omit<AxiosRequestConfig, "url" | "method" | "data">,
) => request<T>({ ...config, url, method: "POST", data }),
patch: <T>(
url: string,
data?: unknown,
config?: Omit<AxiosRequestConfig, "url" | "method" | "data">,
) => request<T>({ ...config, url, method: "PATCH", data }),
put: <T>(
url: string,
data?: unknown,
config?: Omit<AxiosRequestConfig, "url" | "method" | "data">,
) => request<T>({ ...config, url, method: "PUT", data }),
};
export type AdminPingData = { scope: string };
export async function getAdminPing(): Promise<AdminPingData | null> {
if (!baseURL || baseURL === "") {
return null;
}
try {
const data = await adminRequest.get<AdminPingData>(
`${API_V1_PREFIX}/admin/ping`,
);
return data;
} catch {
return null;
}
}