diff --git a/Dockerfile b/Dockerfile index bf91cc7f..3b806177 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,5 +36,5 @@ RUN sed -i "s/__GW_HOST__/${GW_HOST}/g" /etc/nginx/conf.d/default.conf # 暴露端口 EXPOSE 80 -# 启动 Nginx -CMD ["nginx", "-g", "daemon off;"] +# 直接启动 Nginx,避免官方 entrypoint 的 Alpine 包清单检测阻塞容器启动 +ENTRYPOINT ["nginx", "-g", "daemon off;"] diff --git a/src/api/auth/online-user.ts b/src/api/auth/online-user.ts index 1625e58a..c7b242aa 100644 --- a/src/api/auth/online-user.ts +++ b/src/api/auth/online-user.ts @@ -5,13 +5,26 @@ const ONLINE_USER_BASE_URL = "/auth/online-users"; const OnlineUserAPI = { list(queryParams?: OnlineUserQueryParams) { - return request({ + const query = queryParams ?? { pageNum: 1, pageSize: 10 }; + return request< + any, + { records?: OnlineUserItem[]; current?: number; size?: number; total?: number } + >({ url: ONLINE_USER_BASE_URL, method: "get", params: { - username: queryParams?.username || undefined, + pageNum: query.pageNum, + pageSize: query.pageSize, + username: query.username || undefined, }, - }); + }).then((page) => ({ + data: page.records ?? [], + page: { + pageNum: page.current ?? query.pageNum, + pageSize: page.size ?? query.pageSize, + total: page.total ?? 0, + }, + })); }, kickout(sessionId: string) { return request({ diff --git a/src/types/api/online-user.ts b/src/types/api/online-user.ts index b2c2f5e0..0cf2baf3 100644 --- a/src/types/api/online-user.ts +++ b/src/types/api/online-user.ts @@ -3,6 +3,8 @@ */ export interface OnlineUserQueryParams { + pageNum: number; + pageSize: number; username?: string; } diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index f5004940..0d5dc677 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -9,7 +9,12 @@
- + {{ action.label }} @@ -21,7 +26,9 @@
{{ metric.label }} - {{ metric.tag.text }} + + {{ metric.tag.text }} +
{{ metric.value }} @@ -33,7 +40,7 @@ - + - +
-
@@ -103,8 +110,11 @@ defineOptions({ const queryFormRef = ref(); const loading = ref(false); const onlineUsers = ref([]); +const total = ref(0); const queryParams = reactive({ + pageNum: 1, + pageSize: 10, username: "", }); @@ -112,7 +122,8 @@ function fetchData() { loading.value = true; OnlineUserAPI.list(queryParams) .then((data) => { - onlineUsers.value = data ?? []; + onlineUsers.value = data.data ?? []; + total.value = data.page?.total ?? 0; }) .finally(() => { loading.value = false; @@ -120,11 +131,13 @@ function fetchData() { } function handleQuery() { + queryParams.pageNum = 1; fetchData(); } function handleResetQuery() { queryFormRef.value?.resetFields(); + queryParams.pageNum = 1; fetchData(); } diff --git a/tests/unit/views/dashboard-presentation.test.ts b/tests/unit/views/dashboard-presentation.test.ts new file mode 100644 index 00000000..ea81c333 --- /dev/null +++ b/tests/unit/views/dashboard-presentation.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from "vitest"; + +import { aggregateDashboardTrend } from "@/views/dashboard/presentation"; + +describe("dashboard presentation", () => { + it("aggregates request and error series across routes", () => { + const result = aggregateDashboardTrend({ + range: "7d", + start: "2026-09-12T00:00:00Z", + end: "2026-09-19T00:00:00Z", + stepSeconds: 3600, + series: { + tps: JSON.stringify({ + data: { + result: [ + { + metric: { routeId: "a" }, + values: [ + [100, "2"], + [200, "3"], + ], + }, + { + metric: { routeId: "b" }, + values: [ + [100, "1.5"], + [200, "bad"], + ], + }, + ], + }, + }), + errorTps: JSON.stringify({ + data: { result: [{ metric: { routeId: "a" }, values: [[100, "0.5"]] }] }, + }), + }, + }); + + expect(result).toEqual([ + { timestamp: 100, tps: 3.5, errorTps: 0.5 }, + { timestamp: 200, tps: 3, errorTps: 0 }, + ]); + }); +});