88 lines
2.5 KiB
Vue
88 lines
2.5 KiB
Vue
<!-- app/pages/dashboard.vue - 运行状态与最近问答记录页面 -->
|
||
<script lang="ts" setup>
|
||
import { RefreshCw } from "lucide-vue-next";
|
||
|
||
import QaRecordDetail from "@/components/dashboard/QaRecordDetail.vue";
|
||
import QaRecordsTable from "@/components/dashboard/QaRecordsTable.vue";
|
||
import StatsOverview from "@/components/dashboard/StatsOverview.vue";
|
||
import { Button } from "@/components/ui/button";
|
||
import {
|
||
Card,
|
||
CardContent,
|
||
CardDescription,
|
||
CardHeader,
|
||
CardTitle
|
||
} from "@/components/ui/card";
|
||
import { useAnswerStore } from "@/stores/answer";
|
||
import { useAuthStore } from "@/stores/auth";
|
||
|
||
definePageMeta({ middleware: "auth" });
|
||
|
||
const answerStore = useAnswerStore();
|
||
const authStore = useAuthStore();
|
||
|
||
useHead({
|
||
title: "Dashboard - OCS AI 答题服务"
|
||
});
|
||
|
||
/**
|
||
* 客户端 ready 后加载 Dashboard 数据
|
||
*
|
||
* Dashboard 数据来自当前运行中的 Nitro 进程;放到客户端 ready 阶段可以避免
|
||
* `nuxt build` 在构建期等待运行态请求,同时刷新页面后仍会自动拉取真实状态。
|
||
*/
|
||
if (import.meta.client) {
|
||
onNuxtReady(() => {
|
||
void answerStore.loadDashboard();
|
||
});
|
||
}
|
||
|
||
const refreshing = ref(false);
|
||
|
||
const handleRefreshToken = async () => {
|
||
refreshing.value = true;
|
||
await authStore.refreshApiToken();
|
||
refreshing.value = false;
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div class="grid gap-6">
|
||
<!-- OCS 油猴脚本 API token 配置卡片 -->
|
||
<Card v-if="authStore.user?.apiToken">
|
||
<CardHeader>
|
||
<CardTitle>OCS 脚本 Token</CardTitle>
|
||
<CardDescription>
|
||
在 OCS 油猴脚本的服务器配置中填入此
|
||
token,脚本将以你的账号身份调用答题接口。
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div class="flex items-center gap-2">
|
||
<code
|
||
class="flex-1 overflow-x-auto bg-muted px-3 py-2 font-mono text-sm rounded-full"
|
||
>
|
||
{{ authStore.user.apiToken }}
|
||
</code>
|
||
<CopyCom :text="authStore.user.apiToken" :disabled="refreshing" />
|
||
<Button
|
||
variant="outline"
|
||
size="icon"
|
||
:disabled="refreshing"
|
||
title="刷新 Token"
|
||
class="flex items-center gap-1 w-fit px-2.5"
|
||
@click="handleRefreshToken"
|
||
>
|
||
<RefreshCw :class="['size-4', refreshing ? 'animate-spin' : '']" />
|
||
<span>刷新 Token</span>
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<StatsOverview />
|
||
<QaRecordsTable />
|
||
<QaRecordDetail />
|
||
</div>
|
||
</template>
|