From 35ba31a55480dd0ca3b4a9eccecb29fe5ade08df Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Fri, 19 Jun 2026 14:45:26 +0800 Subject: [PATCH] fix: exclude failed accounting from today stats + add click nav to failed records 1. load_dashboard.py: get_today_usage/amount and trend functions now filter out accounting_status='failed' records so failed transactions are not counted as successful. 2. stat_errors.ui: added click bind to navigate to llmage failed accounting records page (app.sage_main_content target). --- dashboard_for_sage/load_dashboard.py | 28 ++++++++++---------- i18n/zh/msg.txt | 38 ++++++++++++++++++++++++++++ wwwroot/stat_errors.ui | 13 ++++++++++ 3 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 i18n/zh/msg.txt diff --git a/dashboard_for_sage/load_dashboard.py b/dashboard_for_sage/load_dashboard.py index db6ea88..adac5c1 100644 --- a/dashboard_for_sage/load_dashboard.py +++ b/dashboard_for_sage/load_dashboard.py @@ -6,22 +6,22 @@ from datetime import datetime, timedelta, date async def get_today_usage(request): - """获取当天llmusage笔数""" + """获取当天llmusage笔数(排除记账失败)""" 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}$" + sql = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${today}$ AND accounting_status != 'failed'" recs = await sor.sqlExe(sql, {'today': today}) cnt = int(recs[0].get('cnt', 0)) if recs else 0 return cnt async def get_today_amount(request): - """获取当天交易金额""" + """获取当天交易金额(排除记账失败)""" 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}$" + sql = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${today}$ AND accounting_status != 'failed'" recs = await sor.sqlExe(sql, {'today': today}) amount = float(recs[0].get('total_amount', 0)) if recs else 0.0 return amount @@ -34,12 +34,12 @@ async def get_usage_trend(request): yesterday = (date.today() - timedelta(days=1)).isoformat() async with get_sor_context(env, 'sage') as sor: # 今日 - sql_today = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${today}$" + sql_today = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${today}$ AND accounting_status != 'failed'" recs_today = await sor.sqlExe(sql_today, {'today': today}) today_cnt = int(recs_today[0].get('cnt', 0)) if recs_today else 0 - + # 昨日 - sql_yesterday = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${yesterday}$" + sql_yesterday = "SELECT COUNT(*) as cnt FROM llmusage WHERE use_date = ${yesterday}$ AND accounting_status != 'failed'" recs_yesterday = await sor.sqlExe(sql_yesterday, {'yesterday': yesterday}) yesterday_cnt = int(recs_yesterday[0].get('cnt', 0)) if recs_yesterday else 0 @@ -66,28 +66,28 @@ async def get_amount_trend(request): yesterday = (date.today() - timedelta(days=1)).isoformat() async with get_sor_context(env, 'sage') as sor: # 今日 - sql_today = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${today}$" + sql_today = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${today}$ AND accounting_status != 'failed'" recs_today = await sor.sqlExe(sql_today, {'today': today}) today_amount = float(recs_today[0].get('total_amount', 0)) if recs_today else 0.0 - + # 昨日 - sql_yesterday = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${yesterday}$" + sql_yesterday = "SELECT COALESCE(SUM(amount), 0) as total_amount FROM llmusage WHERE use_date = ${yesterday}$ AND accounting_status != 'failed'" recs_yesterday = await sor.sqlExe(sql_yesterday, {'yesterday': yesterday}) yesterday_amount = float(recs_yesterday[0].get('total_amount', 0)) if recs_yesterday else 0.0 - + # 计算趋势 if yesterday_amount == 0: return {'trend': 'flat', 'percentage': 0, 'value': today_amount} - + change_pct = ((today_amount - yesterday_amount) / yesterday_amount) * 100 - + if change_pct > 5: trend = 'up' elif change_pct < -5: trend = 'down' else: trend = 'flat' - + return {'trend': trend, 'percentage': abs(change_pct), 'value': today_amount} diff --git a/i18n/zh/msg.txt b/i18n/zh/msg.txt new file mode 100644 index 0000000..a96ef56 --- /dev/null +++ b/i18n/zh/msg.txt @@ -0,0 +1,38 @@ +Cancel: Cancel +Conform: Conform +Discard: Discard +Reset: Reset +Submit: Submit +今日交易金额: 今日交易金额 +今日各模型调用: 今日各模型调用 +今日活跃用户: 今日活跃用户 +今日消费金额: 今日消费金额 +今日调用次数: 今日调用次数 +今日调用笔数: 今日调用笔数 +供应商排行: 供应商排行 +刷新: 刷新 +在线用户: 在线用户 +客户专属监控: 客户专属监控 +当前并发用户: 当前并发用户 +我的今日模型使用: 我的今日模型使用 +排名: 排名 +数据概览: 数据概览 +数据看板: 数据看板 +暂无数据: 暂无数据 +本月各模型调用: 本月各模型调用 +本月新增用户: 本月新增用户 +本月每日调用趋势: 本月每日调用趋势 +本月消费金额: 本月消费金额 +本月调用次数: 本月调用次数 +查看本组织各模型每日/每月调用次数与金额统计: 查看本组织各模型每日/每月调用次数与金额统计 +热门模型: 热门模型 +用户: 用户 +用户总数: 用户总数 +用户排行: 用户排行 +用户金额 TOP 5(今日): 用户金额 TOP 5(今日) +笔数: 笔数 +组织机构数: 组织机构数 +记账异常: 记账异常 +记账错误笔数: 记账错误笔数 +返回首页: 返回首页 +金额: 金额 diff --git a/wwwroot/stat_errors.ui b/wwwroot/stat_errors.ui index 1291fa4..4497849 100644 --- a/wwwroot/stat_errors.ui +++ b/wwwroot/stat_errors.ui @@ -6,8 +6,21 @@ "borderRadius": "12px", "flex": "1", "minHeight": "90px", + "cursor": "pointer", "borderLeft": "4px solid #ef4444" }, + "binds": [ + { + "wid": "self", + "event": "click", + "actiontype": "urlwidget", + "target": "app.sage_main_content", + "options": { + "url": "{{entire_url('/llmage/failed_accounting.ui')}}" + }, + "mode": "replace" + } + ], "subwidgets": [ { "widgettype": "HBox",