对话接口bug修复及后台管理功能完善
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 仪表盘统计数据类型定义
|
||||
export interface UserStats {
|
||||
totalUsers: number
|
||||
todayNewUsers: number
|
||||
activeUsers: number
|
||||
guestUsers: number
|
||||
}
|
||||
|
||||
export interface ContentStats {
|
||||
totalConversations: number
|
||||
totalMessages: number
|
||||
diaryPosts: number
|
||||
communityPosts: number
|
||||
emotionRecords: number
|
||||
}
|
||||
|
||||
export interface AiServiceStats {
|
||||
totalApiCalls: number
|
||||
todayApiCalls: number
|
||||
successfulCalls: number
|
||||
failedCalls: number
|
||||
avgResponseTime: number
|
||||
aiConfigCount: number
|
||||
}
|
||||
|
||||
export interface SystemStats {
|
||||
adminCount: number
|
||||
achievementCount: number
|
||||
rewardCount: number
|
||||
uptime: string
|
||||
}
|
||||
|
||||
export interface RecentActivity {
|
||||
type: string
|
||||
description: string
|
||||
userId: string
|
||||
username: string
|
||||
activityTime: string
|
||||
extraData: Record<string, any>
|
||||
}
|
||||
|
||||
export interface DashboardStats {
|
||||
userStats: UserStats
|
||||
contentStats: ContentStats
|
||||
aiServiceStats: AiServiceStats
|
||||
systemStats: SystemStats
|
||||
recentActivities: RecentActivity[]
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取仪表盘统计数据
|
||||
*/
|
||||
export function getDashboardStats() {
|
||||
return request<DashboardStats>({
|
||||
url: '/admin/dashboard/stats',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户统计数据
|
||||
*/
|
||||
export function getUserStats() {
|
||||
return request<UserStats>({
|
||||
url: '/admin/dashboard/user-stats',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容统计数据
|
||||
*/
|
||||
export function getContentStats() {
|
||||
return request<ContentStats>({
|
||||
url: '/admin/dashboard/content-stats',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AI服务统计数据
|
||||
*/
|
||||
export function getAiServiceStats() {
|
||||
return request<AiServiceStats>({
|
||||
url: '/admin/dashboard/ai-stats',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统统计数据
|
||||
*/
|
||||
export function getSystemStats() {
|
||||
return request<SystemStats>({
|
||||
url: '/admin/dashboard/system-stats',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -1,8 +1,26 @@
|
||||
<template>
|
||||
<div class="dashboard">
|
||||
<h2 class="page-title">仪表盘</h2>
|
||||
<div class="dashboard-header">
|
||||
<h2 class="page-title">仪表盘</h2>
|
||||
<div class="dashboard-actions">
|
||||
<el-text type="info" size="small" v-if="dashboardStats.updateTime">
|
||||
最后更新: {{ new Date(dashboardStats.updateTime).toLocaleString() }}
|
||||
</el-text>
|
||||
<el-text type="success" size="small" v-if="dashboardStats.systemStats.uptime">
|
||||
系统运行: {{ dashboardStats.systemStats.uptime }}
|
||||
</el-text>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
@click="fetchDashboardData"
|
||||
>
|
||||
刷新数据
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="20" class="stats-row">
|
||||
<el-row :gutter="20" class="stats-row" v-loading="loading">
|
||||
<el-col :span="6">
|
||||
<el-card class="stat-card">
|
||||
<div class="stat-content">
|
||||
@@ -10,7 +28,7 @@
|
||||
<el-icon><User /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">1,234</div>
|
||||
<div class="stat-value">{{ dashboardStats.userStats.totalUsers.toLocaleString() }}</div>
|
||||
<div class="stat-label">用户总数</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,7 +42,7 @@
|
||||
<el-icon><UserFilled /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">5</div>
|
||||
<div class="stat-value">{{ dashboardStats.systemStats.adminCount }}</div>
|
||||
<div class="stat-label">管理员总数</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,8 +56,8 @@
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">89</div>
|
||||
<div class="stat-label">今日活跃</div>
|
||||
<div class="stat-value">{{ dashboardStats.userStats.activeUsers.toLocaleString() }}</div>
|
||||
<div class="stat-label">活跃用户</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -52,7 +70,7 @@
|
||||
<el-icon><ChatDotRound /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">456</div>
|
||||
<div class="stat-value">{{ dashboardStats.contentStats.totalConversations.toLocaleString() }}</div>
|
||||
<div class="stat-label">对话总数</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,6 +78,65 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 内容统计行 -->
|
||||
<el-row :gutter="20" class="stats-row" v-loading="loading">
|
||||
<el-col :span="6">
|
||||
<el-card class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon" style="background-color: #909399;">
|
||||
<el-icon><ChatDotRound /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ dashboardStats.contentStats.totalMessages.toLocaleString() }}</div>
|
||||
<div class="stat-label">消息总数</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon" style="background-color: #67c23a;">
|
||||
<el-icon><User /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ dashboardStats.userStats.guestUsers.toLocaleString() }}</div>
|
||||
<div class="stat-label">访客用户</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon" style="background-color: #e6a23c;">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ dashboardStats.contentStats.emotionRecords.toLocaleString() }}</div>
|
||||
<div class="stat-label">情绪记录</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon" style="background-color: #f56c6c;">
|
||||
<el-icon><Setting /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ dashboardStats.aiServiceStats.totalApiCalls.toLocaleString() }}</div>
|
||||
<div class="stat-label">API调用总数</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- AI配置统计 -->
|
||||
<el-row :gutter="20" class="stats-row">
|
||||
<el-col :span="6">
|
||||
@@ -153,10 +230,45 @@ import { ref, reactive, onMounted } from 'vue'
|
||||
import { User, UserFilled, TrendCharts, ChatDotRound, Setting, CircleCheck, CircleClose, Star } from '@element-plus/icons-vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { countEnabledConfigs, countDisabledConfigs, countDefaultConfigs } from '@/api/aiconfig'
|
||||
import { getDashboardStats, type DashboardStats } from '@/api/dashboard'
|
||||
import AiConfigQuickActions from '@/components/AiConfigQuickActions.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const userChartRef = ref<HTMLElement>()
|
||||
|
||||
// 仪表盘统计数据
|
||||
const dashboardStats = reactive<DashboardStats>({
|
||||
userStats: {
|
||||
totalUsers: 0,
|
||||
todayNewUsers: 0,
|
||||
activeUsers: 0,
|
||||
guestUsers: 0
|
||||
},
|
||||
contentStats: {
|
||||
totalConversations: 0,
|
||||
totalMessages: 0,
|
||||
diaryPosts: 0,
|
||||
communityPosts: 0,
|
||||
emotionRecords: 0
|
||||
},
|
||||
aiServiceStats: {
|
||||
totalApiCalls: 0,
|
||||
todayApiCalls: 0,
|
||||
successfulCalls: 0,
|
||||
failedCalls: 0,
|
||||
avgResponseTime: 0,
|
||||
aiConfigCount: 0
|
||||
},
|
||||
systemStats: {
|
||||
adminCount: 0,
|
||||
achievementCount: 0,
|
||||
rewardCount: 0,
|
||||
uptime: ''
|
||||
},
|
||||
recentActivities: [],
|
||||
updateTime: ''
|
||||
})
|
||||
|
||||
const aiStats = reactive({
|
||||
total: 0,
|
||||
enabled: 0,
|
||||
@@ -171,11 +283,35 @@ const recentLogins = ref([
|
||||
{ username: '赵六', time: '15分钟前' }
|
||||
])
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
initUserChart()
|
||||
fetchAiStats()
|
||||
fetchDashboardData()
|
||||
})
|
||||
|
||||
// 获取仪表盘数据
|
||||
const fetchDashboardData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 获取仪表盘统计数据
|
||||
const statsRes = await getDashboardStats()
|
||||
if (statsRes.data) {
|
||||
Object.assign(dashboardStats, statsRes.data)
|
||||
}
|
||||
|
||||
// 获取AI配置统计(保持原有逻辑)
|
||||
await fetchAiStats()
|
||||
|
||||
ElMessage.success('数据加载成功')
|
||||
} catch (error) {
|
||||
console.error('获取仪表盘数据失败:', error)
|
||||
ElMessage.error('数据加载失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取AI配置统计
|
||||
const fetchAiStats = async () => {
|
||||
try {
|
||||
@@ -232,10 +368,23 @@ const initUserChart = () => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dashboard {
|
||||
.page-title {
|
||||
.dashboard-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.dashboard-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
|
||||
Reference in New Issue
Block a user