mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
feat: 丰富公开统计概览数据并添加可选显示项
- 后端:添加 OEM 设置选项控制公开统计显示内容 - publicStatsShowModelDistribution: 模型使用分布 - publicStatsShowTokenTrends: Token 使用趋势(近7天) - publicStatsShowApiKeysTrends: API Keys 活跃趋势(近7天) - publicStatsShowAccountTrends: 账号活跃趋势(近7天) - 后端:扩展 /admin/public-stats API 返回趋势数据 - 前端:PublicStatsOverview 组件支持显示趋势柱状图 - 前端:设置页面添加公开统计选项复选框 - 前端:从登录页移除公开统计概览(已移至首页) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,8 +45,14 @@
|
||||
</div>
|
||||
|
||||
<!-- 模型使用分布 -->
|
||||
<div v-if="authStore.publicStats.modelDistribution?.length > 0" class="mt-4">
|
||||
<div class="mb-2 text-center text-xs text-gray-600 dark:text-gray-400">模型使用分布</div>
|
||||
<div
|
||||
v-if="
|
||||
authStore.publicStats.showOptions?.modelDistribution &&
|
||||
authStore.publicStats.modelDistribution?.length > 0
|
||||
"
|
||||
class="mt-4"
|
||||
>
|
||||
<div class="section-title">模型使用分布</div>
|
||||
<div class="model-distribution">
|
||||
<div
|
||||
v-for="model in authStore.publicStats.modelDistribution"
|
||||
@@ -61,6 +67,80 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Token使用趋势 -->
|
||||
<div
|
||||
v-if="
|
||||
authStore.publicStats.showOptions?.tokenTrends && authStore.publicStats.tokenTrends?.length
|
||||
"
|
||||
class="mt-4"
|
||||
>
|
||||
<div class="section-title">Token 使用趋势(近7天)</div>
|
||||
<div class="trend-chart">
|
||||
<div
|
||||
v-for="(item, index) in authStore.publicStats.tokenTrends"
|
||||
:key="index"
|
||||
class="trend-bar-wrapper"
|
||||
>
|
||||
<div
|
||||
class="trend-bar trend-bar-tokens"
|
||||
:style="{ height: `${getTrendBarHeight(item.tokens, 'tokens')}%` }"
|
||||
:title="`${formatDate(item.date)}: ${formatTokens(item.tokens)} tokens`"
|
||||
></div>
|
||||
<div class="trend-label">{{ formatDateShort(item.date) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Keys 使用趋势 -->
|
||||
<div
|
||||
v-if="
|
||||
authStore.publicStats.showOptions?.apiKeysTrends &&
|
||||
authStore.publicStats.apiKeysTrends?.length
|
||||
"
|
||||
class="mt-4"
|
||||
>
|
||||
<div class="section-title">API Keys 活跃趋势(近7天)</div>
|
||||
<div class="trend-chart">
|
||||
<div
|
||||
v-for="(item, index) in authStore.publicStats.apiKeysTrends"
|
||||
:key="index"
|
||||
class="trend-bar-wrapper"
|
||||
>
|
||||
<div
|
||||
class="trend-bar trend-bar-keys"
|
||||
:style="{ height: `${getTrendBarHeight(item.activeKeys, 'apiKeys')}%` }"
|
||||
:title="`${formatDate(item.date)}: ${item.activeKeys} 个活跃 Key`"
|
||||
></div>
|
||||
<div class="trend-label">{{ formatDateShort(item.date) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账号使用趋势 -->
|
||||
<div
|
||||
v-if="
|
||||
authStore.publicStats.showOptions?.accountTrends &&
|
||||
authStore.publicStats.accountTrends?.length
|
||||
"
|
||||
class="mt-4"
|
||||
>
|
||||
<div class="section-title">账号活跃趋势(近7天)</div>
|
||||
<div class="trend-chart">
|
||||
<div
|
||||
v-for="(item, index) in authStore.publicStats.accountTrends"
|
||||
:key="index"
|
||||
class="trend-bar-wrapper"
|
||||
>
|
||||
<div
|
||||
class="trend-bar trend-bar-accounts"
|
||||
:style="{ height: `${getTrendBarHeight(item.activeAccounts, 'accounts')}%` }"
|
||||
:title="`${formatDate(item.date)}: ${item.activeAccounts} 个活跃账号`"
|
||||
></div>
|
||||
<div class="trend-label">{{ formatDateShort(item.date) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
@@ -70,6 +150,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
@@ -143,6 +224,44 @@ function formatModelName(model) {
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
// 格式化日期
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return ''
|
||||
const parts = dateStr.split('-')
|
||||
if (parts.length === 3) {
|
||||
return `${parts[1]}月${parts[2]}日`
|
||||
}
|
||||
return dateStr
|
||||
}
|
||||
|
||||
// 格式化日期(短格式)
|
||||
function formatDateShort(dateStr) {
|
||||
if (!dateStr) return ''
|
||||
const parts = dateStr.split('-')
|
||||
if (parts.length === 3) {
|
||||
return `${parts[1]}/${parts[2]}`
|
||||
}
|
||||
return dateStr
|
||||
}
|
||||
|
||||
// 计算趋势图柱高度
|
||||
const maxValues = computed(() => {
|
||||
const stats = authStore.publicStats
|
||||
if (!stats) return { tokens: 1, apiKeys: 1, accounts: 1 }
|
||||
|
||||
return {
|
||||
tokens: Math.max(...(stats.tokenTrends?.map((t) => t.tokens) || [1]), 1),
|
||||
apiKeys: Math.max(...(stats.apiKeysTrends?.map((t) => t.activeKeys) || [1]), 1),
|
||||
accounts: Math.max(...(stats.accountTrends?.map((t) => t.activeAccounts) || [1]), 1)
|
||||
}
|
||||
})
|
||||
|
||||
function getTrendBarHeight(value, type) {
|
||||
const max = maxValues.value[type] || 1
|
||||
const height = (value / max) * 100
|
||||
return Math.max(height, 5) // 最小高度5%
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -162,6 +281,11 @@ function formatModelName(model) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 章节标题 */
|
||||
.section-title {
|
||||
@apply mb-2 text-center text-xs text-gray-600 dark:text-gray-400;
|
||||
}
|
||||
|
||||
/* 状态徽章 */
|
||||
.status-badge {
|
||||
@apply inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium;
|
||||
@@ -255,6 +379,36 @@ function formatModelName(model) {
|
||||
@apply w-10 text-right text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
/* 趋势图表 */
|
||||
.trend-chart {
|
||||
@apply flex h-24 items-end justify-between gap-1 rounded-lg bg-gray-50 p-2 dark:bg-gray-700/50;
|
||||
}
|
||||
|
||||
.trend-bar-wrapper {
|
||||
@apply flex flex-1 flex-col items-center;
|
||||
}
|
||||
|
||||
.trend-bar {
|
||||
@apply w-full max-w-8 rounded-t transition-all duration-300;
|
||||
min-height: 4px;
|
||||
}
|
||||
|
||||
.trend-bar-tokens {
|
||||
@apply bg-gradient-to-t from-blue-500 to-blue-400;
|
||||
}
|
||||
|
||||
.trend-bar-keys {
|
||||
@apply bg-gradient-to-t from-green-500 to-green-400;
|
||||
}
|
||||
|
||||
.trend-bar-accounts {
|
||||
@apply bg-gradient-to-t from-purple-500 to-purple-400;
|
||||
}
|
||||
|
||||
.trend-label {
|
||||
@apply mt-1 text-center text-[10px] text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.public-stats-loading {
|
||||
@apply flex items-center justify-center py-8;
|
||||
|
||||
@@ -5,102 +5,92 @@
|
||||
<ThemeToggle mode="dropdown" />
|
||||
</div>
|
||||
|
||||
<div class="flex w-full max-w-4xl flex-col items-center gap-6 lg:flex-row lg:items-start">
|
||||
<!-- 登录卡片 -->
|
||||
<div
|
||||
class="glass-strong w-full max-w-md rounded-xl p-6 shadow-2xl sm:rounded-2xl sm:p-8 md:rounded-3xl md:p-10"
|
||||
>
|
||||
<div class="mb-6 text-center sm:mb-8">
|
||||
<!-- 使用自定义布局来保持登录页面的居中大logo样式 -->
|
||||
<div
|
||||
class="mx-auto mb-4 flex h-16 w-16 items-center justify-center overflow-hidden rounded-xl border border-gray-300/30 bg-gradient-to-br from-blue-500/20 to-purple-500/20 backdrop-blur-sm sm:mb-6 sm:h-20 sm:w-20 sm:rounded-2xl"
|
||||
>
|
||||
<template v-if="!oemLoading">
|
||||
<img
|
||||
v-if="authStore.oemSettings.siteIconData || authStore.oemSettings.siteIcon"
|
||||
alt="Logo"
|
||||
class="h-10 w-10 object-contain sm:h-12 sm:w-12"
|
||||
:src="authStore.oemSettings.siteIconData || authStore.oemSettings.siteIcon"
|
||||
@error="(e) => (e.target.style.display = 'none')"
|
||||
/>
|
||||
<i v-else class="fas fa-cloud text-2xl text-gray-700 sm:text-3xl" />
|
||||
</template>
|
||||
<div v-else class="h-10 w-10 animate-pulse rounded bg-gray-300/50 sm:h-12 sm:w-12" />
|
||||
</div>
|
||||
<template v-if="!oemLoading && authStore.oemSettings.siteName">
|
||||
<h1 class="header-title mb-2 text-2xl font-bold text-white sm:text-3xl">
|
||||
{{ authStore.oemSettings.siteName }}
|
||||
</h1>
|
||||
</template>
|
||||
<div
|
||||
v-else-if="oemLoading"
|
||||
class="mx-auto mb-2 h-8 w-48 animate-pulse rounded bg-gray-300/50 sm:h-9 sm:w-64"
|
||||
/>
|
||||
<p class="text-base text-gray-600 dark:text-gray-400 sm:text-lg">管理后台</p>
|
||||
</div>
|
||||
|
||||
<form class="space-y-4 sm:space-y-6" @submit.prevent="handleLogin">
|
||||
<div>
|
||||
<label
|
||||
class="mb-2 block text-sm font-semibold text-gray-900 dark:text-gray-100 sm:mb-3"
|
||||
for="username"
|
||||
>用户名</label
|
||||
>
|
||||
<input
|
||||
id="username"
|
||||
v-model="loginForm.username"
|
||||
autocomplete="username"
|
||||
class="form-input w-full"
|
||||
name="username"
|
||||
placeholder="请输入用户名"
|
||||
required
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
class="mb-2 block text-sm font-semibold text-gray-900 dark:text-gray-100 sm:mb-3"
|
||||
for="password"
|
||||
>密码</label
|
||||
>
|
||||
<input
|
||||
id="password"
|
||||
v-model="loginForm.password"
|
||||
autocomplete="current-password"
|
||||
class="form-input w-full"
|
||||
name="password"
|
||||
placeholder="请输入密码"
|
||||
required
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="btn btn-primary w-full px-4 py-3 text-base font-semibold sm:px-6 sm:py-4 sm:text-lg"
|
||||
:disabled="authStore.loginLoading"
|
||||
type="submit"
|
||||
>
|
||||
<i v-if="!authStore.loginLoading" class="fas fa-sign-in-alt mr-2" />
|
||||
<div v-if="authStore.loginLoading" class="loading-spinner mr-2" />
|
||||
{{ authStore.loginLoading ? '登录中...' : '登录' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- 登录卡片 -->
|
||||
<div
|
||||
class="glass-strong w-full max-w-md rounded-xl p-6 shadow-2xl sm:rounded-2xl sm:p-8 md:rounded-3xl md:p-10"
|
||||
>
|
||||
<div class="mb-6 text-center sm:mb-8">
|
||||
<!-- 使用自定义布局来保持登录页面的居中大logo样式 -->
|
||||
<div
|
||||
v-if="authStore.loginError"
|
||||
class="mt-4 rounded-lg border border-red-500/30 bg-red-500/20 p-3 text-center text-xs text-red-800 backdrop-blur-sm dark:text-red-400 sm:mt-6 sm:rounded-xl sm:p-4 sm:text-sm"
|
||||
class="mx-auto mb-4 flex h-16 w-16 items-center justify-center overflow-hidden rounded-xl border border-gray-300/30 bg-gradient-to-br from-blue-500/20 to-purple-500/20 backdrop-blur-sm sm:mb-6 sm:h-20 sm:w-20 sm:rounded-2xl"
|
||||
>
|
||||
<i class="fas fa-exclamation-triangle mr-2" />{{ authStore.loginError }}
|
||||
<template v-if="!oemLoading">
|
||||
<img
|
||||
v-if="authStore.oemSettings.siteIconData || authStore.oemSettings.siteIcon"
|
||||
alt="Logo"
|
||||
class="h-10 w-10 object-contain sm:h-12 sm:w-12"
|
||||
:src="authStore.oemSettings.siteIconData || authStore.oemSettings.siteIcon"
|
||||
@error="(e) => (e.target.style.display = 'none')"
|
||||
/>
|
||||
<i v-else class="fas fa-cloud text-2xl text-gray-700 sm:text-3xl" />
|
||||
</template>
|
||||
<div v-else class="h-10 w-10 animate-pulse rounded bg-gray-300/50 sm:h-12 sm:w-12" />
|
||||
</div>
|
||||
<template v-if="!oemLoading && authStore.oemSettings.siteName">
|
||||
<h1 class="header-title mb-2 text-2xl font-bold text-white sm:text-3xl">
|
||||
{{ authStore.oemSettings.siteName }}
|
||||
</h1>
|
||||
</template>
|
||||
<div
|
||||
v-else-if="oemLoading"
|
||||
class="mx-auto mb-2 h-8 w-48 animate-pulse rounded bg-gray-300/50 sm:h-9 sm:w-64"
|
||||
/>
|
||||
<p class="text-base text-gray-600 dark:text-gray-400 sm:text-lg">管理后台</p>
|
||||
</div>
|
||||
|
||||
<!-- 公开统计概览 -->
|
||||
<form class="space-y-4 sm:space-y-6" @submit.prevent="handleLogin">
|
||||
<div>
|
||||
<label
|
||||
class="mb-2 block text-sm font-semibold text-gray-900 dark:text-gray-100 sm:mb-3"
|
||||
for="username"
|
||||
>用户名</label
|
||||
>
|
||||
<input
|
||||
id="username"
|
||||
v-model="loginForm.username"
|
||||
autocomplete="username"
|
||||
class="form-input w-full"
|
||||
name="username"
|
||||
placeholder="请输入用户名"
|
||||
required
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
class="mb-2 block text-sm font-semibold text-gray-900 dark:text-gray-100 sm:mb-3"
|
||||
for="password"
|
||||
>密码</label
|
||||
>
|
||||
<input
|
||||
id="password"
|
||||
v-model="loginForm.password"
|
||||
autocomplete="current-password"
|
||||
class="form-input w-full"
|
||||
name="password"
|
||||
placeholder="请输入密码"
|
||||
required
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="btn btn-primary w-full px-4 py-3 text-base font-semibold sm:px-6 sm:py-4 sm:text-lg"
|
||||
:disabled="authStore.loginLoading"
|
||||
type="submit"
|
||||
>
|
||||
<i v-if="!authStore.loginLoading" class="fas fa-sign-in-alt mr-2" />
|
||||
<div v-if="authStore.loginLoading" class="loading-spinner mr-2" />
|
||||
{{ authStore.loginLoading ? '登录中...' : '登录' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div
|
||||
v-if="authStore.oemSettings.publicStatsEnabled && authStore.publicStats"
|
||||
class="w-full max-w-md lg:max-w-sm"
|
||||
v-if="authStore.loginError"
|
||||
class="mt-4 rounded-lg border border-red-500/30 bg-red-500/20 p-3 text-center text-xs text-red-800 backdrop-blur-sm dark:text-red-400 sm:mt-6 sm:rounded-xl sm:p-4 sm:text-sm"
|
||||
>
|
||||
<PublicStatsOverview />
|
||||
<i class="fas fa-exclamation-triangle mr-2" />{{ authStore.loginError }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,7 +101,6 @@ import { ref, onMounted, computed } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import ThemeToggle from '@/components/common/ThemeToggle.vue'
|
||||
import PublicStatsOverview from '@/components/common/PublicStatsOverview.vue'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const themeStore = useThemeStore()
|
||||
|
||||
@@ -230,6 +230,53 @@
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
启用后,未登录用户可在首页看到服务状态、模型使用分布等概览信息
|
||||
</p>
|
||||
<!-- 公开统计显示选项 -->
|
||||
<div
|
||||
v-if="oemSettings.publicStatsEnabled"
|
||||
class="mt-4 space-y-3 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-600 dark:bg-gray-700/50"
|
||||
>
|
||||
<p class="text-xs font-medium text-gray-700 dark:text-gray-300">
|
||||
选择要公开显示的数据:
|
||||
</p>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowModelDistribution"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">模型使用分布</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowTokenTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>Token 使用趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowApiKeysTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>API Keys 活跃趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowAccountTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>账号活跃趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -415,6 +462,53 @@
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
启用后,未登录用户可在首页看到服务状态、模型使用分布等概览信息
|
||||
</p>
|
||||
<!-- 公开统计显示选项 (移动端) -->
|
||||
<div
|
||||
v-if="oemSettings.publicStatsEnabled"
|
||||
class="mt-4 space-y-3 rounded-lg border border-gray-200 bg-gray-50 p-3 dark:border-gray-600 dark:bg-gray-700/50"
|
||||
>
|
||||
<p class="text-xs font-medium text-gray-700 dark:text-gray-300">
|
||||
选择要公开显示的数据:
|
||||
</p>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowModelDistribution"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">模型使用分布</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowTokenTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>Token 使用趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowApiKeysTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>API Keys 活跃趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="oemSettings.publicStatsShowAccountTrends"
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300"
|
||||
>账号活跃趋势(近7天)</span
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2540,7 +2634,11 @@ const saveOemSettings = async () => {
|
||||
siteIcon: oemSettings.value.siteIcon,
|
||||
siteIconData: oemSettings.value.siteIconData,
|
||||
showAdminButton: oemSettings.value.showAdminButton,
|
||||
publicStatsEnabled: oemSettings.value.publicStatsEnabled
|
||||
publicStatsEnabled: oemSettings.value.publicStatsEnabled,
|
||||
publicStatsShowModelDistribution: oemSettings.value.publicStatsShowModelDistribution,
|
||||
publicStatsShowTokenTrends: oemSettings.value.publicStatsShowTokenTrends,
|
||||
publicStatsShowApiKeysTrends: oemSettings.value.publicStatsShowApiKeysTrends,
|
||||
publicStatsShowAccountTrends: oemSettings.value.publicStatsShowAccountTrends
|
||||
}
|
||||
const result = await settingsStore.saveOemSettings(settings)
|
||||
if (result && result.success) {
|
||||
|
||||
Reference in New Issue
Block a user