feat: 接口统一优化

This commit is contained in:
2026-05-23 13:45:58 +08:00
parent a3b1fba3ea
commit 7d68db723b
20 changed files with 302 additions and 302 deletions
+26 -39
View File
@@ -9,6 +9,7 @@ import type {
QuestionType
} from "@/interfaces";
import { AnswerService } from "@/services";
import { formatUptime, getClientErrorMessage } from "~/utils";
/** Dashboard 最近记录表格每页数量,组件直接复用,避免多个地方写死 */
export const DASHBOARD_RECORD_PAGE_SIZE = 10;
@@ -37,55 +38,44 @@ export const QUESTION_TYPE_LABELS: Record<string, string> = {
completion: "填空题"
};
/** 从 `$fetch` 错误里提取安全文案;服务端已经保证 message/msg 不含敏感上游细节 */
const getClientErrorMessage = (error: unknown, fallback: string) => {
if (typeof error !== "object" || error === null) return fallback;
const data = "data" in error ? (error as { data?: unknown }).data : undefined;
if (typeof data === "object" && data !== null) {
const message = (data as { message?: unknown; msg?: unknown }).message;
const msg = (data as { message?: unknown; msg?: unknown }).msg;
if (typeof message === "string" && message) return message;
if (typeof msg === "string" && msg) return msg;
}
return fallback;
};
/** 把运行秒数格式化为 dashboard 更容易扫读的时长 */
const formatUptime = (seconds: number) => {
const safeSeconds = Math.max(0, Math.floor(seconds));
const days = Math.floor(safeSeconds / 86_400);
const hours = Math.floor((safeSeconds % 86_400) / 3_600);
const minutes = Math.floor((safeSeconds % 3_600) / 60);
if (days > 0) return `${days}${hours} 小时`;
if (hours > 0) return `${hours} 小时 ${minutes} 分钟`;
return `${Math.max(1, minutes)} 分钟`;
};
/** OCS AI 答题服务前端状态管理 */
export const useAnswerStore = defineStore("answer", () => {
// ---- 答题表单状态 ----
/** 当前问题内容 */
const question = ref("");
/** 当前问题类型 */
const questionType = ref<QuestionType>("");
/** 当前问题选项 */
const options = ref("");
/** 答题请求加载状态 */
const searchLoading = ref(false);
/** 答题结果 */
const answerResult = ref<ISearchSuccessResponse>();
/** 答题错误文案 */
const searchErrorMessage = ref("");
// ---- Dashboard 状态 ----
/** 健康检查信息 */
const health = ref<IHealthResponse>();
/** 运行统计信息 */
const stats = ref<IStatsResponse>();
/** 最近问答记录 */
const records = ref<IQaRecord[]>([]);
/** Dashboard 错误文案 */
const dashboardErrorMessage = ref("");
/** 统计信息加载状态 */
const statsLoading = ref(false);
/** 最近问答记录加载状态 */
const recordsLoading = ref(false);
/** 缓存清理状态 */
const cacheClearing = ref(false);
/** 最近问答记录当前页码 */
const recordsPage = ref(1);
/** 最近问答记录每页数量 */
const recordsPageSize = ref(DASHBOARD_RECORD_PAGE_SIZE);
/** 最近问答记录总数 */
const recordCount = ref(0);
/** 当前选中的问答记录 */
const selectedRecord = ref<IQaRecord>();
/** Dashboard 表格当前页数据,页码切换会重新请求服务端分页接口 */
@@ -154,7 +144,7 @@ export const useAnswerStore = defineStore("answer", () => {
const getHealth = async () => {
try {
const res = await AnswerService.getHealth();
health.value = res.data;
health.value = res.data.data;
} catch (error) {
dashboardErrorMessage.value = getClientErrorMessage(
error,
@@ -168,7 +158,7 @@ export const useAnswerStore = defineStore("answer", () => {
statsLoading.value = true;
try {
const res = await AnswerService.getStats();
stats.value = res.data;
stats.value = res.data.data;
} catch (error) {
dashboardErrorMessage.value = getClientErrorMessage(
error,
@@ -187,10 +177,10 @@ export const useAnswerStore = defineStore("answer", () => {
page,
size: recordsPageSize.value
});
records.value = res.data.records;
recordsPage.value = res.data.page;
recordsPageSize.value = res.data.size;
recordCount.value = res.data.total;
records.value = res.data.data.records;
recordsPage.value = res.data.data.page;
recordsPageSize.value = res.data.data.size;
recordCount.value = res.data.data.total;
} catch (error) {
dashboardErrorMessage.value = getClientErrorMessage(
error,
@@ -207,16 +197,13 @@ export const useAnswerStore = defineStore("answer", () => {
await Promise.allSettled([getHealth(), getStats(), getRecords()]);
};
/** 清空缓存和问答记录后刷新统计与表格 */
/** 清空缓存后刷新统计与表格$fetch 非 2xx 时会抛出,错误由 catch 处理 */
const clearCache = async () => {
cacheClearing.value = true;
dashboardErrorMessage.value = "";
try {
const res = await AnswerService.clearCache();
if (!res.data.success) {
dashboardErrorMessage.value = res.data.message;
}
await AnswerService.clearCache();
await Promise.allSettled([getStats(), getRecords(1)]);
} catch (error) {
dashboardErrorMessage.value = getClientErrorMessage(