feat: 前端样式调整

This commit is contained in:
tbphp
2025-07-04 22:46:35 +08:00
parent c1b9e9d247
commit 3f9439b11f
10 changed files with 81 additions and 82 deletions

View File

@@ -17,7 +17,7 @@ import {
import { onMounted, ref, watch } from "vue";
interface Props {
group: Group;
group: Group | null;
}
const props = defineProps<Props>();
@@ -38,6 +38,11 @@ watch(
);
async function loadStats() {
if (!props.group) {
stats.value = null;
return;
}
try {
loading.value = true;
stats.value = await keysApi.getGroupStats(props.group.id);
@@ -69,6 +74,17 @@ function formatNumber(num: number): string {
function formatPercentage(num: number): string {
return `${num.toFixed(1)}%`;
}
function copyUrl(url: string) {
navigator.clipboard
.writeText(url)
.then(() => {
window.$message.success("地址已复制到剪贴板");
})
.catch(() => {
window.$message.error("复制失败");
});
}
</script>
<template>
@@ -78,7 +94,14 @@ function formatPercentage(num: number): string {
<div class="card-header">
<div class="header-left">
<h3 class="group-title">
{{ group.display_name || group.name }}
{{ group?.display_name || group?.name || "请选择分组" }}
<code
v-if="group"
class="group-url"
@click="copyUrl(`https://gpt-load.com/${group?.name}`)"
>
https://gpt-load.com/{{ group?.name }}
</code>
</h3>
</div>
<div class="header-actions">
@@ -114,33 +137,36 @@ function formatPercentage(num: number): string {
<!-- 统计摘要区 -->
<div class="stats-summary">
<n-spin :show="loading" size="small">
<n-grid v-if="stats" :cols="5" :x-gap="12" :y-gap="12" responsive="screen">
<n-grid :cols="5" :x-gap="12" :y-gap="12" responsive="screen">
<n-grid-item span="1">
<n-card :title="`${stats.active_keys} / ${stats.total_keys}`" size="large">
<n-card
:title="`${stats?.active_keys || 0} / ${stats?.total_keys || 0}`"
size="large"
>
<template #header-extra><span class="status-title">密钥数量</span></template>
</n-card>
</n-grid-item>
<n-grid-item span="1">
<n-card
class="status-card-failure"
:title="formatPercentage(stats.failure_rate_24h)"
:title="formatPercentage(stats?.failure_rate_24h || 0)"
size="large"
>
<template #header-extra><span class="status-title">失败率</span></template>
</n-card>
</n-grid-item>
<n-grid-item span="1">
<n-card :title="formatNumber(stats.requests_1h)" size="large">
<n-card :title="formatNumber(stats?.requests_1h || 0)" size="large">
<template #header-extra><span class="status-title">近1小时</span></template>
</n-card>
</n-grid-item>
<n-grid-item span="1">
<n-card :title="formatNumber(stats.requests_24h)" size="large">
<n-card :title="formatNumber(stats?.requests_24h || 0)" size="large">
<template #header-extra><span class="status-title">近24小时</span></template>
</n-card>
</n-grid-item>
<n-grid-item span="1">
<n-card :title="formatNumber(stats.requests_7d)" size="large">
<n-card :title="formatNumber(stats?.requests_7d || 0)" size="large">
<template #header-extra><span class="status-title">近7天</span></template>
</n-card>
</n-grid-item>
@@ -156,13 +182,15 @@ function formatPercentage(num: number): string {
<div class="detail-section">
<h4 class="section-title">基础信息</h4>
<n-descriptions :column="2" size="small">
<n-descriptions-item label="分组名称">{{ group.name }}</n-descriptions-item>
<n-descriptions-item label="渠道类型">
{{ group.channel_type }}
<n-descriptions-item label="分组名称">
{{ group?.name || "-" }}
</n-descriptions-item>
<n-descriptions-item label="排序">{{ group.sort }}</n-descriptions-item>
<n-descriptions-item v-if="group.description" label="描述" :span="2">
{{ group.description }}
<n-descriptions-item label="渠道类型">
{{ group?.channel_type || "openai" }}
</n-descriptions-item>
<n-descriptions-item label="排序">{{ group?.sort || 0 }}</n-descriptions-item>
<n-descriptions-item v-if="group?.description || ''" label="描述" :span="2">
{{ group?.description || "" }}
</n-descriptions-item>
</n-descriptions>
</div>
@@ -171,7 +199,7 @@ function formatPercentage(num: number): string {
<h4 class="section-title">上游地址</h4>
<n-descriptions :column="1" size="small">
<n-descriptions-item
v-for="(upstream, index) in group.upstreams"
v-for="(upstream, index) in group?.upstreams ?? []"
:key="index"
:label="`上游 ${index + 1}`"
>
@@ -186,19 +214,19 @@ function formatPercentage(num: number): string {
<div class="detail-section">
<h4 class="section-title">配置信息</h4>
<n-descriptions :column="2" size="small">
<n-descriptions-item v-if="group.config.test_model" label="测试模型">
{{ group.config.test_model }}
<n-descriptions-item v-if="group?.config?.test_model || ''" label="测试模型">
{{ group?.config?.test_model || "" }}
</n-descriptions-item>
<n-descriptions-item v-if="group.config.request_timeout" label="请求超时">
{{ group.config.request_timeout }}ms
<n-descriptions-item v-if="group?.config?.request_timeout || 0" label="请求超时">
{{ group?.config?.request_timeout || 0 }}ms
</n-descriptions-item>
<n-descriptions-item
v-if="Object.keys(group.config.param_overrides || {}).length > 0"
v-if="Object.keys(group?.config?.param_overrides || {}).length > 0"
label="参数覆盖"
:span="2"
>
<pre class="config-json">{{
JSON.stringify(group.config.param_overrides, null, 2)
JSON.stringify(group?.config?.param_overrides || "", null, 2)
}}</pre>
</n-descriptions-item>
</n-descriptions>
@@ -245,6 +273,17 @@ function formatPercentage(num: number): string {
margin: 0 0 8px 0;
}
.group-url {
font-size: 0.8rem;
color: #2563eb;
margin-left: 8px;
font-family: monospace;
background: rgba(37, 99, 235, 0.1);
border-radius: 4px;
padding: 2px 6px;
margin-right: 4px;
}
/* .group-meta {
display: flex;
align-items: center;