feat: add user-level model usage chart (我的今日模型使用)
- Add get_user_today_models() function to load_dashboard.py Shows current user's today model call counts and amounts - Create api/user_today_models.dspy endpoint - Create user_today_models_chart.ui ChartBar widget (30s auto-refresh) - Add '我的今日模型使用' card section to index.ui with refresh button - Register new paths in load_path.py (logined permission)
This commit is contained in:
parent
c36ada56b1
commit
69b7ec5cd0
@ -238,6 +238,37 @@ async def get_total_orgs(request):
|
||||
return cnt
|
||||
|
||||
|
||||
async def get_user_today_models(request):
|
||||
"""获取当前用户当天各模型调用次数和金额(用户级监控项)"""
|
||||
env = request._run_ns
|
||||
userid = await env.get_user()
|
||||
if not userid:
|
||||
return []
|
||||
today = env.curDateString()
|
||||
async with get_sor_context(env, 'sage') as sor:
|
||||
sql = """
|
||||
SELECT
|
||||
COALESCE(b.name, 'Unknown') as model_name,
|
||||
COUNT(*) as cnt,
|
||||
COALESCE(SUM(a.amount), 0) as total_amount
|
||||
FROM llmusage a
|
||||
LEFT JOIN llm b ON a.llmid = b.id
|
||||
WHERE a.use_date = ${today}$
|
||||
AND a.userid = ${userid}$
|
||||
GROUP BY a.llmid, b.name
|
||||
ORDER BY cnt DESC
|
||||
"""
|
||||
recs = await sor.sqlExe(sql, {'today': today, 'userid': userid})
|
||||
result = []
|
||||
for r in recs:
|
||||
result.append({
|
||||
'model_name': r.get('model_name', 'Unknown'),
|
||||
'cnt': int(r.get('cnt', 0)),
|
||||
'total_amount': round(float(r.get('total_amount', 0)), 4)
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
def load_dashboard():
|
||||
"""Register dashboard functions on ServerEnv"""
|
||||
g = ServerEnv()
|
||||
@ -254,3 +285,4 @@ def load_dashboard():
|
||||
g.get_active_users_today = get_active_users_today
|
||||
g.get_new_users_month = get_new_users_month
|
||||
g.get_total_orgs = get_total_orgs
|
||||
g.get_user_today_models = get_user_today_models
|
||||
|
||||
@ -67,9 +67,11 @@ paths = [
|
||||
# Charts
|
||||
("/dashboard_for_sage/chart_top_models.ui", "logined"),
|
||||
("/dashboard_for_sage/top_models_chart.ui", "logined"),
|
||||
("/dashboard_for_sage/user_today_models_chart.ui", "logined"),
|
||||
|
||||
# API endpoints
|
||||
("/dashboard_for_sage/api/top_models.dspy", "logined"),
|
||||
("/dashboard_for_sage/api/user_today_models.dspy", "logined"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
6
wwwroot/api/user_today_models.dspy
Normal file
6
wwwroot/api/user_today_models.dspy
Normal file
@ -0,0 +1,6 @@
|
||||
# coding=utf-8
|
||||
"""User's today model usage data API for ChartBar"""
|
||||
import json
|
||||
|
||||
models = await get_user_today_models(request)
|
||||
return json.dumps(models, ensure_ascii=False, default=str)
|
||||
@ -412,6 +412,65 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {
|
||||
"css": "card",
|
||||
"width": "100%",
|
||||
"borderRadius": "12px",
|
||||
"padding": "20px",
|
||||
"marginTop": "20px"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {
|
||||
"width": "100%",
|
||||
"alignItems": "center",
|
||||
"marginBottom": "16px"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"fontWeight": "600",
|
||||
"otext": "我的今日模型使用",
|
||||
"i18n": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Filler"
|
||||
},
|
||||
{
|
||||
"widgettype": "Button",
|
||||
"options": {
|
||||
"label": "刷新",
|
||||
"border": "none",
|
||||
"borderRadius": "6px",
|
||||
"padding": "4px 12px",
|
||||
"fontSize": "12px"
|
||||
},
|
||||
"binds": [
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "method",
|
||||
"target": "-@ChartBar",
|
||||
"method": "render_urldata",
|
||||
"params": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "urlwidget",
|
||||
"options": {
|
||||
"url": "{{entire_url('user_today_models_chart.ui')}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {
|
||||
|
||||
11
wwwroot/user_today_models_chart.ui
Normal file
11
wwwroot/user_today_models_chart.ui
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"widgettype": "ChartBar",
|
||||
"options": {
|
||||
"height": "280px",
|
||||
"width": "100%",
|
||||
"data_url": "{{entire_url('api/user_today_models.dspy')}}",
|
||||
"nameField": "model_name",
|
||||
"valueFields": ["cnt", "total_amount"],
|
||||
"refresh_period": 30
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user