refactor(data): consolidate data layer under services namespace

- Move src/data/{api,dto,schemas} directories to src/data/services/*
- Update all relative imports across the codebase to reference new paths
- Use CSS color tokens for splash button gradient in splash-button.module.css
- Add responsive sizes attribute to splash background image
- Add JSDoc documentation to splash-background component referencing original Dart implementation
This commit is contained in:
2026-06-09 16:44:05 +08:00
parent 763bec4e74
commit 661e417619
98 changed files with 57 additions and 44 deletions
@@ -0,0 +1,85 @@
/**
* 日志拦截器
*
* 在开发模式下记录请求/响应/错误日志。
* 原始 Dart: lib/core/net/interceptor/app_interceptor.dart 中的日志部分。
*/
import type { FetchHook } from "ofetch";
const TAG = "[API]";
function isDev(): boolean {
return process.env.NODE_ENV !== "production";
}
function getRequestUrl(request: Request | string): string {
return typeof request === "string" ? request : request.url;
}
function getRequestMethod(
request: Request | string,
options: { method?: string }
): string {
return request instanceof Request ? request.method : options.method ?? "GET";
}
function formatBody(body: unknown): string {
if (body === undefined || body === null) return "";
try {
if (body instanceof FormData) {
const entries: string[] = [];
body.forEach((value, key) => {
if (value instanceof File) {
entries.push(`${key}=File(${value.name})`);
} else {
entries.push(`${key}=${String(value)}`);
}
});
return `FormData{${entries.join(", ")}}`;
}
return JSON.stringify(body);
} catch {
return String(body);
}
}
export const onRequestLogging: FetchHook = async (ctx) => {
if (!isDev()) return;
const method = getRequestMethod(ctx.request, ctx.options);
const url = getRequestUrl(ctx.request);
console.log(
`${TAG}${method} ${url}`,
ctx.options.body !== undefined ? formatBody(ctx.options.body) : ""
);
};
export const onResponseLogging: FetchHook = async (ctx) => {
if (!isDev() || !ctx.response) return;
const method = getRequestMethod(ctx.request, ctx.options);
const url = getRequestUrl(ctx.request);
console.log(
`${TAG}${ctx.response.status} ${method} ${url}`,
formatBody(ctx.response._data)
);
};
export const onErrorLogging: FetchHook = async (ctx) => {
if (!isDev()) return;
const status = ctx.response?.status ?? "N/A";
const method = getRequestMethod(ctx.request, ctx.options);
const url = getRequestUrl(ctx.request);
console.error(
`${TAG}${status} ${method} ${url}`,
ctx.error?.message ?? "Unknown error"
);
};
/**
* 兼容旧接口的 FetchHooks 形式(保留以备兼容)
*/
export const loggingInterceptor = {
onRequest: onRequestLogging,
onResponse: onResponseLogging,
onResponseError: onErrorLogging,
onRequestError: onErrorLogging,
};