4009214cbc
CI / docker (push) Successful in 7m4s
引入用户端对话/生图与管理端 Provider 配置,统一 invoke 编排、Gateway、请求日志与模型管理;前端按设计规范拆分布局,Go module 更名为 github.com/rose_cat707/Atlas;生图长任务 SSE 推送;管理端登录防爆破;协议与服务类型联动;Replicate 模型同步修复;用户端创作台 UI 重构;管理端创作历史替代请求日志。 Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.9 KiB
Vue
58 lines
1.9 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import api from '@/api/client'
|
|
import PageHeader from '@/components/PageHeader.vue'
|
|
import StatCard from '@/components/StatCard.vue'
|
|
import AppCard from '@/components/AppCard.vue'
|
|
|
|
const { t } = useI18n()
|
|
const loading = ref(true)
|
|
const stats = ref({
|
|
total_requests: 0,
|
|
success_rate: 0,
|
|
avg_latency_ms: 0,
|
|
file_count: 0,
|
|
file_bytes: 0,
|
|
})
|
|
const appInfo = ref({ app_name: 'Atlas', data_dir: '' })
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const [dash, st] = await Promise.all([
|
|
api.get('/dashboard'),
|
|
api.get('/admin/dashboard/stats'),
|
|
])
|
|
appInfo.value = dash.data
|
|
stats.value = st.data
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
})
|
|
|
|
function formatBytes(n: number) {
|
|
if (n < 1024) return `${n} B`
|
|
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`
|
|
return `${(n / 1024 / 1024).toFixed(1)} MB`
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<PageHeader :title="t('dashboard.title')" />
|
|
<div v-loading="loading" class="stat-grid">
|
|
<StatCard :label="t('admin.stats.requests')" :value="stats.total_requests" />
|
|
<StatCard :label="t('admin.stats.successRate')" :value="`${Math.round(stats.success_rate * 100)}%`" />
|
|
<StatCard :label="t('admin.stats.latency')" :value="`${Math.round(stats.avg_latency_ms)} ms`" />
|
|
<StatCard :label="t('admin.stats.files')" :value="formatBytes(stats.file_bytes)" />
|
|
</div>
|
|
<AppCard padded :title="t('dashboard.title')" style="margin-top: 16px">
|
|
<el-descriptions :column="1" border>
|
|
<el-descriptions-item :label="t('dashboard.appName')">{{ appInfo.app_name }}</el-descriptions-item>
|
|
<el-descriptions-item :label="t('dashboard.dataDir')">{{ appInfo.data_dir }}</el-descriptions-item>
|
|
<el-descriptions-item :label="t('admin.stats.fileCount')">{{ stats.file_count }}</el-descriptions-item>
|
|
</el-descriptions>
|
|
</AppCard>
|
|
</div>
|
|
</template>
|