feat: 6个监控组件改用RefreshWidget+Jinja2服务端渲染,初始即加载+60s刷新

This commit is contained in:
yumoqing 2026-07-22 14:56:20 +08:00
parent 482c0fac8b
commit 7db361425b
9 changed files with 137 additions and 111 deletions

View File

@ -398,6 +398,62 @@ async def j2_avg_ttft(request):
return 0 return 0
# ── 监控组件 j2 函数,每段独立 .ui 通过 RefreshWidget 加载 ──
async def j2_model_perf_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await api_model_perf(sor)
except Exception:
return []
async def j2_currency_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await get_currency_breakdown(env, sor)
except Exception:
return []
async def j2_provider_roi_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await api_provider_roi(sor)
except Exception:
return []
async def j2_top_models_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await get_top_models(env, sor)
except Exception:
return []
async def j2_top_users_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await get_top_users(env, sor)
except Exception:
return []
async def j2_top_providers_data(request):
try:
env = request._run_ns
async with get_sor_context(env, MODULE_NAME) as sor:
return await get_top_providers(env, sor)
except Exception:
return []
# ── Cron ETL ── # ── Cron ETL ──
async def cron_etl_sync(request): async def cron_etl_sync(request):
@ -457,6 +513,12 @@ def load_sage_datamart():
env.j2_online_users = j2_online_users env.j2_online_users = j2_online_users
env.j2_scoped_success_rate = j2_scoped_success_rate env.j2_scoped_success_rate = j2_scoped_success_rate
env.j2_scoped_fail_count = j2_scoped_fail_count env.j2_scoped_fail_count = j2_scoped_fail_count
env.j2_model_perf_data = j2_model_perf_data
env.j2_currency_data = j2_currency_data
env.j2_provider_roi_data = j2_provider_roi_data
env.j2_top_models_data = j2_top_models_data
env.j2_top_users_data = j2_top_users_data
env.j2_top_providers_data = j2_top_providers_data
env.cron_etl_sync = cron_etl_sync env.cron_etl_sync = cron_etl_sync
env.cron_etl_aggregate = cron_etl_aggregate env.cron_etl_aggregate = cron_etl_aggregate
env.cron_etl_provider_cost = cron_etl_provider_cost env.cron_etl_provider_cost = cron_etl_provider_cost

View File

@ -35,6 +35,12 @@ PATHS_LOGINED = [
f"/{MOD}/rt_card_online.ui", f"/{MOD}/rt_card_online.ui",
f"/{MOD}/rt_card_success.ui", f"/{MOD}/rt_card_success.ui",
f"/{MOD}/rt_card_fail.ui", f"/{MOD}/rt_card_fail.ui",
f"/{MOD}/sect_model_perf.ui",
f"/{MOD}/sect_currency.ui",
f"/{MOD}/sect_provider_roi.ui",
f"/{MOD}/sect_top_models.ui",
f"/{MOD}/sect_top_users.ui",
f"/{MOD}/sect_top_providers.ui",
] ]
def run(role, path): def run(role, path):

View File

@ -20,13 +20,13 @@
"widgettype": "HBox", "widgettype": "HBox",
"options": {"width": "100%", "gap": "12px", "marginBottom": "16px", "flexWrap": "wrap"}, "options": {"width": "100%", "gap": "12px", "marginBottom": "16px", "flexWrap": "wrap"},
"subwidgets": [ "subwidgets": [
{"widgettype": "RefreshWidget", "id": "rt_calls", "options": {"period_seconds": 15, "url": "{{entire_url('rt_card_calls.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_calls", "options": {"period_seconds": 15, "url": "{{entire_url('rt_card_calls.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_amount", "options": {"period_seconds": 15, "url": "{{entire_url('rt_card_amount.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_amount", "options": {"period_seconds": 15, "url": "{{entire_url('rt_card_amount.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_users", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_users.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_users", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_users.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_active", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_active.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_active", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_active.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_online", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_online.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_online", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_online.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_success", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_success.ui')}}", "width": "13%"}}, {"widgettype": "RefreshWidget", "id": "rt_success","options": {"period_seconds": 30, "url": "{{entire_url('rt_card_success.ui')}}", "width": "13%"}},
{"widgettype": "RefreshWidget", "id": "rt_fail", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_fail.ui')}}", "width": "13%"}} {"widgettype": "RefreshWidget", "id": "rt_fail", "options": {"period_seconds": 30, "url": "{{entire_url('rt_card_fail.ui')}}", "width": "13%"}}
] ]
}, },
{ {
@ -38,25 +38,7 @@
"options": {"css": "card", "width": "60%", "padding": "16px"}, "options": {"css": "card", "width": "60%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "模型性能排行", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "模型性能排行", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_model_perf.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 24,
"data_url": "{{entire_url('api/model_perf.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${model}", "width": "35%"}},
{"widgettype": "Text", "options": {"text": "${avg_ttft_ms}ms", "width": "15%"}},
{"widgettype": "Text", "options": {"text": "${success_rate}%", "width": "15%"}},
{"widgettype": "Text", "options": {"text": "${total_calls}", "width": "15%"}},
{"widgettype": "Text", "options": {"text": "${total_amount_cny}", "width": "20%"}}
]
}
}
}
] ]
}, },
{ {
@ -64,24 +46,7 @@
"options": {"css": "card", "width": "40%", "padding": "16px"}, "options": {"css": "card", "width": "40%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "币种分布", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "币种分布", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_currency.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 24,
"data_url": "{{entire_url('api/currency_stats.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${currency}", "width": "20%"}},
{"widgettype": "Text", "options": {"text": "${call_count}次", "width": "25%"}},
{"widgettype": "Text", "options": {"text": "${amount}", "width": "25%"}},
{"widgettype": "Text", "options": {"text": "${amount_cny}", "width": "30%"}}
]
}
}
}
] ]
} }
] ]
@ -95,25 +60,7 @@
"options": {"css": "card", "width": "50%", "padding": "16px"}, "options": {"css": "card", "width": "50%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "供应商性价比", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "供应商性价比", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_provider_roi.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 24,
"data_url": "{{entire_url('api/provider_roi.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${model}", "width": "35%"}},
{"widgettype": "Text", "options": {"text": "${unit_price}/t", "width": "20%"}},
{"widgettype": "Text", "options": {"text": "${avg_ttft_ms}ms", "width": "15%"}},
{"widgettype": "Text", "options": {"text": "${total_calls}次", "width": "15%"}},
{"widgettype": "Text", "options": {"text": "${total_amount_cny}", "width": "15%"}}
]
}
}
}
] ]
} }
] ]
@ -127,23 +74,7 @@
"options": {"css": "card", "width": "33%", "padding": "16px"}, "options": {"css": "card", "width": "33%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "热门模型", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "热门模型", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_top_models.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 20,
"data_url": "{{entire_url('api/top_models.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${model_name}", "width": "50%"}},
{"widgettype": "Text", "options": {"text": "${cnt}次", "width": "25%"}},
{"widgettype": "Text", "options": {"text": "${total_amount}", "width": "25%"}}
]
}
}
}
] ]
}, },
{ {
@ -151,23 +82,7 @@
"options": {"css": "card", "width": "33%", "padding": "16px"}, "options": {"css": "card", "width": "33%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "用户排行", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "用户排行", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_top_users.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 20,
"data_url": "{{entire_url('api/top_users.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${user_name}", "width": "50%"}},
{"widgettype": "Text", "options": {"text": "${cnt}次", "width": "25%"}},
{"widgettype": "Text", "options": {"text": "${total_amount}", "width": "25%"}}
]
}
}
}
] ]
}, },
{ {
@ -175,23 +90,7 @@
"options": {"css": "card", "width": "33%", "padding": "16px"}, "options": {"css": "card", "width": "33%", "padding": "16px"},
"subwidgets": [ "subwidgets": [
{"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "供应商排行", "i18n": true, "marginBottom": "8px"}}, {"widgettype": "Title4", "options": {"fontWeight": "600", "otext": "供应商排行", "i18n": true, "marginBottom": "8px"}},
{ {"widgettype": "RefreshWidget", "options": {"period_seconds": 60, "url": "{{entire_url('sect_top_providers.ui')}}", "width": "100%"}}
"widgettype": "Cols",
"options": {
"col_cwidth": 20,
"data_url": "{{entire_url('api/top_providers.dspy')}}",
"data_params": {},
"record_view": {
"widgettype": "HBox",
"options": {"cheight": 3, "width": "100%"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "${provider_name}", "width": "50%"}},
{"widgettype": "Text", "options": {"text": "${cnt}次", "width": "25%"}},
{"widgettype": "Text", "options": {"text": "${total_amount}", "width": "25%"}}
]
}
}
}
] ]
} }
] ]

10
wwwroot/sect_currency.ui Normal file
View File

@ -0,0 +1,10 @@
{% set data = j2_currency_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('currency',''),ensure_ascii=False)}},"width":"20%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('call_count',0)|string)+'次',ensure_ascii=False)}},"width":"25%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('amount',0)|string,ensure_ascii=False)}},"width":"25%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('amount_cny',0)|string,ensure_ascii=False)}},"width":"30%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}

View File

@ -0,0 +1,11 @@
{% set data = j2_model_perf_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('model',''),ensure_ascii=False)}},"width":"35%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('avg_ttft_ms','')|string)+'ms',ensure_ascii=False)}},"width":"15%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('success_rate','')|string)+'%',ensure_ascii=False)}},"width":"15%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_calls','')|string,ensure_ascii=False)}},"width":"15%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_amount_cny','')|string,ensure_ascii=False)}},"width":"20%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}

View File

@ -0,0 +1,11 @@
{% set data = j2_provider_roi_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('model',''),ensure_ascii=False)}},"width":"35%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('unit_price','')|string)+'/t',ensure_ascii=False)}},"width":"20%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('avg_ttft_ms','')|string)+'ms',ensure_ascii=False)}},"width":"15%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('total_calls',0)|string)+'次',ensure_ascii=False)}},"width":"15%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_amount_cny',0)|string,ensure_ascii=False)}},"width":"15%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}

View File

@ -0,0 +1,9 @@
{% set data = j2_top_models_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('model_name',''),ensure_ascii=False)}},"width":"50%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('cnt',0)|string)+'次',ensure_ascii=False)}},"width":"25%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_amount',0)|string,ensure_ascii=False)}},"width":"25%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}

View File

@ -0,0 +1,9 @@
{% set data = j2_top_providers_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('provider_name',''),ensure_ascii=False)}},"width":"50%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('cnt',0)|string)+'次',ensure_ascii=False)}},"width":"25%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_amount',0)|string,ensure_ascii=False)}},"width":"25%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}

View File

@ -0,0 +1,9 @@
{% set data = j2_top_users_data(request) %}
{"widgettype":"VBox","options":{"width":"100%"},"subwidgets":[
{% for r in data %}
{"widgettype":"HBox","options":{"cheight":3,"width":"100%"},"subwidgets":[
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('user_name',''),ensure_ascii=False)}},"width":"50%"}},
{"widgettype":"Text","options":{"text":{{json.dumps((r.get('cnt',0)|string)+'次',ensure_ascii=False)}},"width":"25%"}},
{"widgettype":"Text","options":{"text":{{json.dumps(r.get('total_amount',0)|string,ensure_ascii=False)}},"width":"25%"}}
]}{% if not loop.last %},{% endif %}{% endfor %}
]}