feat: 看板优化——中文标题+Token消耗+时间段筛选+品牌名统一

- 学员端:LoginPanel/App.vue 描述文案优化,去掉生硬表述
- 后台品牌统一:index.html/App.vue 标题改为'大本营千问千答'
- 看板tab:Dashboard -> 数据看板
- 看板新增:输入Token、输出Token、总Token 统计
- 看板支持按时间段筛选:后端API增加start/end参数,前端加日期选择器
- stats-grid布局从5列调整为4列,响应式改为2列
This commit is contained in:
2026-07-09 14:58:45 +08:00
parent facb3a6a56
commit 0ea75dea1d
10 changed files with 84 additions and 20 deletions

View File

@@ -60,13 +60,35 @@ class AdminAuthService:
class AdminDashboardService:
@staticmethod
def stats(db: Session) -> dict:
def stats(db: Session, start: datetime | None = None, end: datetime | None = None) -> dict:
from sqlalchemy import and_
# 基础表查询条件(时间范围)
user_filter = [User.is_deleted == 0]
session_filter = [ChatSession.is_deleted == 0]
msg_filter = []
ai_filter = []
if start:
user_filter.append(User.created_at >= start)
session_filter.append(ChatSession.created_at >= start)
msg_filter.append(ChatMessage.created_at >= start)
ai_filter.append(AiRequestLog.created_at >= start)
if end:
user_filter.append(User.created_at <= end)
session_filter.append(ChatSession.created_at <= end)
msg_filter.append(ChatMessage.created_at <= end)
ai_filter.append(AiRequestLog.created_at <= end)
return {
"userCount": db.scalar(select(func.count(User.id)).where(User.is_deleted == 0)) or 0,
"sessionCount": db.scalar(select(func.count(ChatSession.id)).where(ChatSession.is_deleted == 0)) or 0,
"messageCount": db.scalar(select(func.count(ChatMessage.id))) or 0,
"aiRequestCount": db.scalar(select(func.count(AiRequestLog.id))) or 0,
"userCount": db.scalar(select(func.count(User.id)).where(and_(*user_filter))) or 0,
"sessionCount": db.scalar(select(func.count(ChatSession.id)).where(and_(*session_filter))) or 0,
"messageCount": db.scalar(select(func.count(ChatMessage.id)).where(and_(*msg_filter))) or 0,
"aiRequestCount": db.scalar(select(func.count(AiRequestLog.id)).where(and_(*ai_filter))) or 0,
"knowledgeCount": db.scalar(select(func.count(Knowledge.id))) or 0,
"inputToken": db.scalar(select(func.coalesce(func.sum(AiRequestLog.input_token), 0)).where(and_(*ai_filter))) or 0,
"outputToken": db.scalar(select(func.coalesce(func.sum(AiRequestLog.output_token), 0)).where(and_(*ai_filter))) or 0,
"totalToken": db.scalar(select(func.coalesce(func.sum(AiRequestLog.total_token), 0)).where(and_(*ai_filter))) or 0,
}