dashboard_for_sage/wwwroot/api/get_user_stats.dspy
yumoqing d2210a2996 refactor: use RefreshWidget for stat cards + fix .dspy import violations
Architecture:
- index.ui: title + RefreshWidget(cards) + ChartBar with refresh_period
- RefreshWidget wraps dashboard_cards.dspy → returns full card widget tree
  with live data (cnt, amount, total_users, concurrent_users)
- ChartBar handles its own auto-refresh via refresh_period: 10
- No more JS polling file needed

.dspy import fixes:
- get_today_usage.dspy: remove import json, from datetime import date
- get_user_stats.dspy: remove from datetime import datetime, timedelta
- get_top_models.dspy: remove from datetime import date
- All use pre-loaded datetime module (datetime.date.today(), etc.)
- dashboard_cards.dspy: same pattern, no imports

Permission:
- load_path.py: add dashboard_cards.dspy logined
2026-05-24 16:45:45 +08:00

32 lines
991 B
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""获取当前用户总数和并发用户数近5分钟有活跃记录的用户"""
# datetime, json, DBPools 由 ahserver 预加载,无需 import
now = datetime.datetime.now()
five_min_ago = (now - datetime.timedelta(minutes=5)).strftime('%Y-%m-%d %H:%M:%S')
today = now.strftime('%Y-%m-%d')
sql_users = "SELECT COUNT(*) as total_users FROM users"
sql_concurrent = """
SELECT COUNT(DISTINCT userid) as concurrent_users
FROM llmusage
WHERE use_date = ${today}$
AND use_time >= ${five_min_ago}$
"""
db = DBPools()
async with db.sqlorContext('sage') as sor:
user_recs = await sor.sqlExe(sql_users, {})
total_users = int(user_recs[0].get('total_users', 0)) if user_recs else 0
conc_recs = await sor.sqlExe(sql_concurrent, {
'today': today,
'five_min_ago': five_min_ago
})
concurrent_users = int(conc_recs[0].get('concurrent_users', 0)) if conc_recs else 0
return {
'total_users': total_users,
'concurrent_users': concurrent_users
}