From 753887a4e2d566288b92b231dde042ecaecb0f7b Mon Sep 17 00:00:00 2001 From: yumoqing Date: Mon, 25 May 2026 11:19:24 +0800 Subject: [PATCH] bugfix --- dashboard_for_sage/load_dashboard.py | 128 +++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 5 deletions(-) diff --git a/dashboard_for_sage/load_dashboard.py b/dashboard_for_sage/load_dashboard.py index 4bcae23..9400bee 100644 --- a/dashboard_for_sage/load_dashboard.py +++ b/dashboard_for_sage/load_dashboard.py @@ -6,8 +6,8 @@ from datetime import datetime, timedelta, date async def get_today_usage(request): """获取当天llmusage笔数""" - today = env.curDateString() env = request._run_ns + today = env.curDateString() async with get_sor_context(env, 'sage') as sor: sql = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${today}$" recs = await sor.sqlExe(sql, {'today': today}) @@ -17,8 +17,8 @@ async def get_today_usage(request): async def get_today_amount(request): """获取当天交易金额""" - today = env.curDateString() env = request._run_ns + today = env.curDateString() async with get_sor_context(env, 'sage') as sor: sql = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${today}$" recs = await sor.sqlExe(sql, {'today': today}) @@ -40,8 +40,8 @@ async def get_concurrent_users(request): """获取当前并发用户数(近5分钟有活跃记录的用户)""" now = datetime.now() five_min_ago = (now - timedelta(minutes=5)).strftime('%Y-%m-%d %H:%M:%S') - today = env.curDateString() env = request._run_ns + today = env.curDateString() async with get_sor_context(env, 'sage') as sor: sql = """ SELECT COUNT(DISTINCT userid) as concurrent_users @@ -57,8 +57,8 @@ async def get_concurrent_users(request): async def get_top_models(request): """获取当天排名前三的模型(返回记录列表,供ChartBar使用)""" # today = date.today().isoformat() - today = env.curDateString() env = request._run_ns + today = env.curDateString() async with get_sor_context(env, 'sage') as sor: sql = """ SELECT @@ -85,8 +85,8 @@ async def get_top_models(request): async def get_accounting_errors(request): """获取当天记账错误笔数(accounting_status='failed')""" - today = env.curDateString() env = request._run_ns + today = env.curDateString() async with get_sor_context(env, 'sage') as sor: sql = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${today}$ AND accounting_status = 'failed'" recs = await sor.sqlExe(sql, {'today': today}) @@ -94,6 +94,120 @@ async def get_accounting_errors(request): return cnt +async def get_top_users_by_amount(request): + """获取当天用户金额前5""" + env = request._run_ns + today = env.curDateString() + async with get_sor_context(env, 'sage') as sor: + sql = """ + SELECT + COALESCE(b.nick_name, b.username) as user_name, + COALESCE(SUM(a.amount), 0) as total_amount, + COUNT(*) as cnt + FROM llmusage a + LEFT JOIN users b ON a.userid = b.id + WHERE a.use_date = ${today}$ + GROUP BY a.userid, b.nick_name, b.username + ORDER BY total_amount DESC + LIMIT 5 + """ + recs = await sor.sqlExe(sql, {'today': today}) + result = [] + for r in recs: + result.append({ + 'user_name': r.get('user_name', 'Unknown'), + 'total_amount': round(float(r.get('total_amount', 0)), 2), + 'cnt': int(r.get('cnt', 0)) + }) + return result + + +async def get_top_users_by_count(request): + """获取当天用户笔数前5""" + env = request._run_ns + today = env.curDateString() + async with get_sor_context(env, 'sage') as sor: + sql = """ + SELECT + COALESCE(b.nick_name, b.username) as user_name, + COUNT(*) as cnt, + COALESCE(SUM(a.amount), 0) as total_amount + FROM llmusage a + LEFT JOIN users b ON a.userid = b.id + WHERE a.use_date = ${today}$ + GROUP BY a.userid, b.nick_name, b.username + ORDER BY cnt DESC + LIMIT 5 + """ + recs = await sor.sqlExe(sql, {'today': today}) + result = [] + for r in recs: + result.append({ + 'user_name': r.get('user_name', 'Unknown'), + 'cnt': int(r.get('cnt', 0)), + 'total_amount': round(float(r.get('total_amount', 0)), 2) + }) + return result + + +async def get_top_providers_by_amount(request): + """获取模型供应商金额前5""" + env = request._run_ns + today = env.curDateString() + async with get_sor_context(env, 'sage') as sor: + sql = """ + SELECT + COALESCE(c.orgname, 'Unknown') as provider_name, + COALESCE(SUM(a.amount), 0) as total_amount, + COUNT(*) as cnt + FROM llmusage a + LEFT JOIN llm b ON a.llmid = b.id + LEFT JOIN organization c ON b.providerid = c.id + WHERE a.use_date = ${today}$ + GROUP BY b.providerid, c.orgname + ORDER BY total_amount DESC + LIMIT 5 + """ + recs = await sor.sqlExe(sql, {'today': today}) + result = [] + for r in recs: + result.append({ + 'provider_name': r.get('provider_name', 'Unknown'), + 'total_amount': round(float(r.get('total_amount', 0)), 2), + 'cnt': int(r.get('cnt', 0)) + }) + return result + + +async def get_top_providers_by_count(request): + """获取模型供应商笔数前5""" + env = request._run_ns + today = env.curDateString() + async with get_sor_context(env, 'sage') as sor: + sql = """ + SELECT + COALESCE(c.orgname, 'Unknown') as provider_name, + COUNT(*) as cnt, + COALESCE(SUM(a.amount), 0) as total_amount + FROM llmusage a + LEFT JOIN llm b ON a.llmid = b.id + LEFT JOIN organization c ON b.providerid = c.id + WHERE a.use_date = ${today}$ + GROUP BY b.providerid, c.orgname + ORDER BY cnt DESC + LIMIT 5 + """ + recs = await sor.sqlExe(sql, {'today': today}) + result = [] + for r in recs: + result.append({ + 'provider_name': r.get('provider_name', 'Unknown'), + 'cnt': int(r.get('cnt', 0)), + 'total_amount': round(float(r.get('total_amount', 0)), 2) + }) + return result + + def load_dashboard(): """Register dashboard functions on ServerEnv""" g = ServerEnv() @@ -103,3 +217,7 @@ def load_dashboard(): g.get_concurrent_users = get_concurrent_users g.get_top_models = get_top_models g.get_accounting_errors = get_accounting_errors + g.get_top_users_by_amount = get_top_users_by_amount + g.get_top_users_by_count = get_top_users_by_count + g.get_top_providers_by_amount = get_top_providers_by_amount + g.get_top_providers_by_count = get_top_providers_by_count