feat: 添加分页功能和缓存管理,优化问答记录展示
This commit is contained in:
@@ -58,7 +58,7 @@ defineExpose({ isCopied });
|
||||
:variant="variant"
|
||||
:size="size"
|
||||
:disabled="disabled"
|
||||
:class="cn('relative overflow-hidden pl-8', className)"
|
||||
:class="cn('relative overflow-hidden pl-7', className)"
|
||||
@click.prevent.stop="handleCopy"
|
||||
>
|
||||
<!-- 复制成功图标:未复制时向上移出,复制后滑入 -->
|
||||
|
||||
@@ -14,8 +14,19 @@ import {
|
||||
CardHeader,
|
||||
CardTitle
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue
|
||||
} from "@/components/ui/select";
|
||||
import type { IQaRecord } from "@/interfaces";
|
||||
import { QUESTION_TYPE_LABELS, useAnswerStore } from "@/stores/answer";
|
||||
import {
|
||||
DASHBOARD_PAGE_SIZE_OPTIONS,
|
||||
QUESTION_TYPE_LABELS,
|
||||
useAnswerStore
|
||||
} from "@/stores/answer";
|
||||
|
||||
const answerStore = useAnswerStore();
|
||||
const {
|
||||
@@ -78,8 +89,29 @@ const displayOptions = (record: IQaRecord) => {
|
||||
<template>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>最近问答记录</CardTitle>
|
||||
<CardDescription>当前进程最多保留最近 100 条。</CardDescription>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div>
|
||||
<CardTitle>最近问答记录</CardTitle>
|
||||
<CardDescription>分页展示,按创建时间倒序</CardDescription>
|
||||
</div>
|
||||
<Select
|
||||
:model-value="String(recordsPageSize)"
|
||||
@update:model-value="(v) => answerStore.setRecordsPageSize(Number(v))"
|
||||
>
|
||||
<SelectTrigger class="w-28">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem
|
||||
v-for="size in DASHBOARD_PAGE_SIZE_OPTIONS"
|
||||
:key="size"
|
||||
:value="String(size)"
|
||||
>
|
||||
{{ size }} 条/页
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
import { RefreshCw, Trash2 } from "lucide-vue-next";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription
|
||||
} from "@/components/ui/alert";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
@@ -39,13 +36,7 @@ const overviewItems = computed(() => [
|
||||
{
|
||||
label: "模型",
|
||||
value: stats.value?.model || health.value?.model || "-",
|
||||
detail: stats.value?.cache_enabled ? "缓存已启用" : "缓存未启用",
|
||||
loading: statsLoading.value && !stats.value
|
||||
},
|
||||
{
|
||||
label: "缓存数量",
|
||||
value: stats.value?.cache_size?.toString() ?? "0",
|
||||
detail: "当前进程",
|
||||
detail: "AI 模型",
|
||||
loading: statsLoading.value && !stats.value
|
||||
},
|
||||
{
|
||||
@@ -59,7 +50,9 @@ const overviewItems = computed(() => [
|
||||
|
||||
<template>
|
||||
<section class="grid gap-4">
|
||||
<div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
|
||||
<div
|
||||
class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between"
|
||||
>
|
||||
<div>
|
||||
<h1 class="text-xl font-semibold text-foreground">Dashboard</h1>
|
||||
<p class="mt-1 text-sm text-muted-foreground">
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!-- app/components/home/OcsConfigCard.vue - OCS AnswererWrapper 配置片段 -->
|
||||
<script lang="ts" setup>
|
||||
import { RefreshCw } from "lucide-vue-next";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardAction,
|
||||
@@ -12,6 +15,14 @@ import { useAuthStore } from "@/stores/auth";
|
||||
const authStore = useAuthStore();
|
||||
const origin = ref("http://localhost:3000");
|
||||
|
||||
const refreshing = ref(false);
|
||||
|
||||
const handleRefreshToken = async () => {
|
||||
refreshing.value = true;
|
||||
await authStore.refreshApiToken();
|
||||
refreshing.value = false;
|
||||
};
|
||||
|
||||
/** 浏览器端读取当前站点地址,避免文档里写死 localhost 或生产域名 */
|
||||
onMounted(() => {
|
||||
origin.value = window.location.origin;
|
||||
@@ -22,7 +33,8 @@ const configText = computed(() => {
|
||||
const data: Record<string, string> = {
|
||||
title: "${title}",
|
||||
type: "${type}",
|
||||
options: "${options}"
|
||||
options: "${options}",
|
||||
token: ""
|
||||
};
|
||||
|
||||
if (authStore.user?.apiToken) {
|
||||
@@ -53,13 +65,25 @@ const configText = computed(() => {
|
||||
<CardHeader>
|
||||
<CardTitle>OCS 配置</CardTitle>
|
||||
<CardAction>
|
||||
<CopyCom :text="configText" :timeout="1200" />
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
v-if="authStore.user?.apiToken && authStore.isOnline"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:disabled="refreshing"
|
||||
@click="handleRefreshToken"
|
||||
>
|
||||
<RefreshCw :class="['size-4', refreshing ? 'animate-spin' : '']" />
|
||||
刷新 Token
|
||||
</Button>
|
||||
<CopyCom :text="configText" :timeout="1200" :disabled="refreshing" />
|
||||
</div>
|
||||
</CardAction>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<pre
|
||||
class="max-h-120 overflow-auto rounded-2xl bg-muted p-4 text-xs leading-5 text-muted-foreground"
|
||||
class="h-89.5 overflow-x-auto overflow-y-hidden rounded-2xl bg-muted p-4 text-xs leading-5 text-muted-foreground"
|
||||
><code>{{ configText }}</code>
|
||||
</pre>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user