feat: 客户dashboard新增按用户统计(今日/本月+总计)
load_dashboard.py: - get_customer_users_today: 今日各用户调用次数+金额,含总计行 - get_customer_users_month: 本月各用户调用次数+金额,含总计行 customer_usage.ui: 底部嵌入 customer_users_table.ui customer_users_table.ui: 左右双栏 Tabular(今日|本月) api/: customer_users_today.dspy + customer_users_month.dspy scripts/load_path.py: +3条路径注册
This commit is contained in:
parent
dfad387358
commit
4028d00584
@ -586,6 +586,99 @@ async def get_customer_daily_trend(request):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
async def get_customer_users_today(request):
|
||||||
|
"""获取当前客户组织今日各用户使用统计(含总计行)"""
|
||||||
|
env = request._run_ns
|
||||||
|
org_id = await _get_org_id(request)
|
||||||
|
today = env.curDateString()
|
||||||
|
async with get_sor_context(env, 'sage') as sor:
|
||||||
|
sql = """
|
||||||
|
SELECT
|
||||||
|
a.userid,
|
||||||
|
COALESCE(b.nick_name, b.username) as user_name,
|
||||||
|
COUNT(*) as call_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}$
|
||||||
|
AND a.userorgid = ${org_id}$
|
||||||
|
GROUP BY a.userid, b.nick_name, b.username
|
||||||
|
ORDER BY call_cnt DESC
|
||||||
|
"""
|
||||||
|
recs = await sor.sqlExe(sql, {'today': today, 'org_id': org_id})
|
||||||
|
result = []
|
||||||
|
total_calls = 0
|
||||||
|
total_amount = 0.0
|
||||||
|
for r in recs:
|
||||||
|
c = int(r.get('call_cnt', 0))
|
||||||
|
a = round(float(r.get('total_amount', 0)), 4)
|
||||||
|
total_calls += c
|
||||||
|
total_amount += a
|
||||||
|
result.append({
|
||||||
|
'user_name': r.get('user_name', 'Unknown'),
|
||||||
|
'call_cnt': c,
|
||||||
|
'total_amount': a
|
||||||
|
})
|
||||||
|
# 追加总计行
|
||||||
|
result.append({
|
||||||
|
'user_name': '【合计】',
|
||||||
|
'call_cnt': total_calls,
|
||||||
|
'total_amount': round(total_amount, 4)
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
async def get_customer_users_month(request):
|
||||||
|
"""获取当前客户组织当月各用户使用统计(含总计行)"""
|
||||||
|
env = request._run_ns
|
||||||
|
org_id = await _get_org_id(request)
|
||||||
|
now = datetime.now()
|
||||||
|
month_start = now.strftime('%Y-%m-01')
|
||||||
|
if now.month == 12:
|
||||||
|
month_end = f'{now.year + 1}-01-01'
|
||||||
|
else:
|
||||||
|
month_end = f'{now.year}-{now.month + 1:02d}-01'
|
||||||
|
async with get_sor_context(env, 'sage') as sor:
|
||||||
|
sql = """
|
||||||
|
SELECT
|
||||||
|
a.userid,
|
||||||
|
COALESCE(b.nick_name, b.username) as user_name,
|
||||||
|
COUNT(*) as call_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 >= ${month_start}$
|
||||||
|
AND a.use_date < ${month_end}$
|
||||||
|
AND a.userorgid = ${org_id}$
|
||||||
|
GROUP BY a.userid, b.nick_name, b.username
|
||||||
|
ORDER BY call_cnt DESC
|
||||||
|
"""
|
||||||
|
recs = await sor.sqlExe(sql, {
|
||||||
|
'month_start': month_start,
|
||||||
|
'month_end': month_end,
|
||||||
|
'org_id': org_id
|
||||||
|
})
|
||||||
|
result = []
|
||||||
|
total_calls = 0
|
||||||
|
total_amount = 0.0
|
||||||
|
for r in recs:
|
||||||
|
c = int(r.get('call_cnt', 0))
|
||||||
|
a = round(float(r.get('total_amount', 0)), 4)
|
||||||
|
total_calls += c
|
||||||
|
total_amount += a
|
||||||
|
result.append({
|
||||||
|
'user_name': r.get('user_name', 'Unknown'),
|
||||||
|
'call_cnt': c,
|
||||||
|
'total_amount': a
|
||||||
|
})
|
||||||
|
result.append({
|
||||||
|
'user_name': '【合计】',
|
||||||
|
'call_cnt': total_calls,
|
||||||
|
'total_amount': round(total_amount, 4)
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def load_dashboard():
|
def load_dashboard():
|
||||||
"""Register dashboard functions on ServerEnv"""
|
"""Register dashboard functions on ServerEnv"""
|
||||||
g = ServerEnv()
|
g = ServerEnv()
|
||||||
@ -613,3 +706,5 @@ def load_dashboard():
|
|||||||
g.get_customer_daily_summary = get_customer_daily_summary
|
g.get_customer_daily_summary = get_customer_daily_summary
|
||||||
g.get_customer_month_summary = get_customer_month_summary
|
g.get_customer_month_summary = get_customer_month_summary
|
||||||
g.get_customer_daily_trend = get_customer_daily_trend
|
g.get_customer_daily_trend = get_customer_daily_trend
|
||||||
|
g.get_customer_users_today = get_customer_users_today
|
||||||
|
g.get_customer_users_month = get_customer_users_month
|
||||||
|
|||||||
@ -79,6 +79,7 @@ paths = [
|
|||||||
("/dashboard_for_sage/customer_daily_chart.ui", "logined"),
|
("/dashboard_for_sage/customer_daily_chart.ui", "logined"),
|
||||||
("/dashboard_for_sage/customer_monthly_chart.ui", "logined"),
|
("/dashboard_for_sage/customer_monthly_chart.ui", "logined"),
|
||||||
("/dashboard_for_sage/customer_daily_trend.ui", "logined"),
|
("/dashboard_for_sage/customer_daily_trend.ui", "logined"),
|
||||||
|
("/dashboard_for_sage/customer_users_table.ui", "logined"),
|
||||||
|
|
||||||
# API endpoints
|
# API endpoints
|
||||||
("/dashboard_for_sage/api/top_models.dspy", "logined"),
|
("/dashboard_for_sage/api/top_models.dspy", "logined"),
|
||||||
@ -87,6 +88,8 @@ paths = [
|
|||||||
("/dashboard_for_sage/api/customer_daily_models.dspy", "logined"),
|
("/dashboard_for_sage/api/customer_daily_models.dspy", "logined"),
|
||||||
("/dashboard_for_sage/api/customer_monthly_models.dspy", "logined"),
|
("/dashboard_for_sage/api/customer_monthly_models.dspy", "logined"),
|
||||||
("/dashboard_for_sage/api/customer_daily_trend.dspy", "logined"),
|
("/dashboard_for_sage/api/customer_daily_trend.dspy", "logined"),
|
||||||
|
("/dashboard_for_sage/api/customer_users_today.dspy", "logined"),
|
||||||
|
("/dashboard_for_sage/api/customer_users_month.dspy", "logined"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
wwwroot/api/customer_users_month.dspy
Normal file
6
wwwroot/api/customer_users_month.dspy
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
"""Customer per-user month usage API"""
|
||||||
|
import json
|
||||||
|
|
||||||
|
users = await get_customer_users_month(request)
|
||||||
|
return json.dumps(users, ensure_ascii=False, default=str)
|
||||||
6
wwwroot/api/customer_users_today.dspy
Normal file
6
wwwroot/api/customer_users_today.dspy
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
"""Customer per-user today usage API"""
|
||||||
|
import json
|
||||||
|
|
||||||
|
users = await get_customer_users_today(request)
|
||||||
|
return json.dumps(users, ensure_ascii=False, default=str)
|
||||||
@ -10,290 +10,20 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"css": "filler"
|
"css": "filler"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"alignItems": "center",
|
|
||||||
"marginBottom": "24px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Title2",
|
|
||||||
"options": {
|
|
||||||
"fontWeight": "700",
|
|
||||||
"otext": "客户专属监控",
|
|
||||||
"i18n": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Filler"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Button",
|
|
||||||
"options": {
|
|
||||||
"label": "返回首页",
|
|
||||||
"borderRadius": "6px",
|
|
||||||
"padding": "6px 16px",
|
|
||||||
"fontSize": "13px"
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "urlwidget",
|
|
||||||
"target": "app.sage_main_content",
|
|
||||||
"options": {
|
|
||||||
"url": "{{entire_url('/dashboard_for_sage/index.ui')}}"
|
|
||||||
},
|
|
||||||
"mode": "replace"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "ResponsableBox",
|
|
||||||
"options": {
|
|
||||||
"gap": "16px",
|
|
||||||
"minWidth": "220px",
|
|
||||||
"marginBottom": "24px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-card",
|
|
||||||
"padding": "20px",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"flex": "1",
|
|
||||||
"minHeight": "110px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"alignItems": "center",
|
|
||||||
"marginBottom": "12px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Svg",
|
|
||||||
"options": {
|
|
||||||
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 3v18h18\"/><path d=\"M18 17V9\"/><path d=\"M13 17V5\"/><path d=\"M8 17v-3\"/></svg>",
|
|
||||||
"width": "24px",
|
|
||||||
"height": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Filler"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-value",
|
|
||||||
"text": "{{get_customer_daily_summary(request).cnt}}",
|
|
||||||
"fontSize": "32px",
|
|
||||||
"fontWeight": "700",
|
|
||||||
"lineHeight": "1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-label",
|
|
||||||
"fontSize": "14px",
|
|
||||||
"marginTop": "4px",
|
|
||||||
"otext": "今日调用次数",
|
|
||||||
"i18n": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-card",
|
|
||||||
"padding": "20px",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"flex": "1",
|
|
||||||
"minHeight": "110px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"alignItems": "center",
|
|
||||||
"marginBottom": "12px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Svg",
|
|
||||||
"options": {
|
|
||||||
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 6v12m6-6H6\"/></svg>",
|
|
||||||
"width": "24px",
|
|
||||||
"height": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Filler"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-value",
|
|
||||||
"text": "¥{{get_customer_daily_summary(request).total_amount|round(2)}}",
|
|
||||||
"fontSize": "32px",
|
|
||||||
"fontWeight": "700",
|
|
||||||
"lineHeight": "1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-label",
|
|
||||||
"fontSize": "14px",
|
|
||||||
"marginTop": "4px",
|
|
||||||
"otext": "今日消费金额",
|
|
||||||
"i18n": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-card",
|
|
||||||
"padding": "20px",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"flex": "1",
|
|
||||||
"minHeight": "110px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"alignItems": "center",
|
|
||||||
"marginBottom": "12px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Svg",
|
|
||||||
"options": {
|
|
||||||
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/></svg>",
|
|
||||||
"width": "24px",
|
|
||||||
"height": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Filler"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-value",
|
|
||||||
"text": "{{get_customer_month_summary(request).cnt}}",
|
|
||||||
"fontSize": "32px",
|
|
||||||
"fontWeight": "700",
|
|
||||||
"lineHeight": "1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-label",
|
|
||||||
"fontSize": "14px",
|
|
||||||
"marginTop": "4px",
|
|
||||||
"otext": "本月调用次数",
|
|
||||||
"i18n": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-card",
|
|
||||||
"padding": "20px",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"flex": "1",
|
|
||||||
"minHeight": "110px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"alignItems": "center",
|
|
||||||
"marginBottom": "12px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Svg",
|
|
||||||
"options": {
|
|
||||||
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"23\"/><path d=\"M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6\"/></svg>",
|
|
||||||
"width": "24px",
|
|
||||||
"height": "24px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Filler"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-value",
|
|
||||||
"text": "¥{{get_customer_month_summary(request).total_amount|round(2)}}",
|
|
||||||
"fontSize": "32px",
|
|
||||||
"fontWeight": "700",
|
|
||||||
"lineHeight": "1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"css": "stat-label",
|
|
||||||
"fontSize": "14px",
|
|
||||||
"marginTop": "4px",
|
|
||||||
"otext": "本月消费金额",
|
|
||||||
"i18n": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "card",
|
|
||||||
"width": "100%",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"padding": "20px",
|
|
||||||
"marginBottom": "20px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "HBox",
|
"widgettype": "HBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"marginBottom": "16px"
|
"marginBottom": "24px"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Title4",
|
"widgettype": "Title2",
|
||||||
"options": {
|
"options": {
|
||||||
"fontWeight": "600",
|
"fontWeight": "700",
|
||||||
"otext": "本月每日调用趋势",
|
"otext": "客户专属监控",
|
||||||
"i18n": true
|
"i18n": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -303,20 +33,424 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Button",
|
"widgettype": "Button",
|
||||||
"options": {
|
"options": {
|
||||||
"label": "刷新",
|
"label": "返回首页",
|
||||||
"border": "none",
|
|
||||||
"borderRadius": "6px",
|
"borderRadius": "6px",
|
||||||
"padding": "4px 12px",
|
"padding": "6px 16px",
|
||||||
"fontSize": "12px"
|
"fontSize": "13px"
|
||||||
},
|
},
|
||||||
"binds": [
|
"binds": [
|
||||||
{
|
{
|
||||||
"wid": "self",
|
"wid": "self",
|
||||||
"event": "click",
|
"event": "click",
|
||||||
"actiontype": "method",
|
"actiontype": "urlwidget",
|
||||||
"target": "-@ChartLine",
|
"target": "app.sage_main_content",
|
||||||
"method": "render_urldata",
|
"options": {
|
||||||
"params": {}
|
"url": "{{entire_url('/dashboard_for_sage/index.ui')}}"
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "ResponsableBox",
|
||||||
|
"options": {
|
||||||
|
"gap": "16px",
|
||||||
|
"minWidth": "220px",
|
||||||
|
"marginBottom": "24px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-card",
|
||||||
|
"padding": "20px",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"flex": "1",
|
||||||
|
"minHeight": "110px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"alignItems": "center",
|
||||||
|
"marginBottom": "12px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 3v18h18\"/><path d=\"M18 17V9\"/><path d=\"M13 17V5\"/><path d=\"M8 17v-3\"/></svg>",
|
||||||
|
"width": "24px",
|
||||||
|
"height": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Filler"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-value",
|
||||||
|
"text": "{{get_customer_daily_summary(request).cnt}}",
|
||||||
|
"fontSize": "32px",
|
||||||
|
"fontWeight": "700",
|
||||||
|
"lineHeight": "1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-label",
|
||||||
|
"fontSize": "14px",
|
||||||
|
"marginTop": "4px",
|
||||||
|
"otext": "今日调用次数",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-card",
|
||||||
|
"padding": "20px",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"flex": "1",
|
||||||
|
"minHeight": "110px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"alignItems": "center",
|
||||||
|
"marginBottom": "12px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 6v12m6-6H6\"/></svg>",
|
||||||
|
"width": "24px",
|
||||||
|
"height": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Filler"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-value",
|
||||||
|
"text": "¥{{get_customer_daily_summary(request).total_amount|round(2)}}",
|
||||||
|
"fontSize": "32px",
|
||||||
|
"fontWeight": "700",
|
||||||
|
"lineHeight": "1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-label",
|
||||||
|
"fontSize": "14px",
|
||||||
|
"marginTop": "4px",
|
||||||
|
"otext": "今日消费金额",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-card",
|
||||||
|
"padding": "20px",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"flex": "1",
|
||||||
|
"minHeight": "110px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"alignItems": "center",
|
||||||
|
"marginBottom": "12px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/></svg>",
|
||||||
|
"width": "24px",
|
||||||
|
"height": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Filler"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-value",
|
||||||
|
"text": "{{get_customer_month_summary(request).cnt}}",
|
||||||
|
"fontSize": "32px",
|
||||||
|
"fontWeight": "700",
|
||||||
|
"lineHeight": "1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-label",
|
||||||
|
"fontSize": "14px",
|
||||||
|
"marginTop": "4px",
|
||||||
|
"otext": "本月调用次数",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-card",
|
||||||
|
"padding": "20px",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"flex": "1",
|
||||||
|
"minHeight": "110px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"alignItems": "center",
|
||||||
|
"marginBottom": "12px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"svg": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"23\"/><path d=\"M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6\"/></svg>",
|
||||||
|
"width": "24px",
|
||||||
|
"height": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Filler"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-value",
|
||||||
|
"text": "¥{{get_customer_month_summary(request).total_amount|round(2)}}",
|
||||||
|
"fontSize": "32px",
|
||||||
|
"fontWeight": "700",
|
||||||
|
"lineHeight": "1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"css": "stat-label",
|
||||||
|
"fontSize": "14px",
|
||||||
|
"marginTop": "4px",
|
||||||
|
"otext": "本月消费金额",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "card",
|
||||||
|
"width": "100%",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"padding": "20px",
|
||||||
|
"marginBottom": "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": "-@ChartLine",
|
||||||
|
"method": "render_urldata",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('customer_daily_trend.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"gap": "20px",
|
||||||
|
"marginBottom": "20px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "card",
|
||||||
|
"width": "50%",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"padding": "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('customer_daily_chart.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "card",
|
||||||
|
"width": "50%",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"padding": "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('customer_monthly_chart.ui')}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -325,138 +459,10 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('customer_daily_trend.ui')}}"
|
"url": "{{entire_url('customer_users_table.ui')}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"gap": "20px",
|
|
||||||
"marginBottom": "20px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "card",
|
|
||||||
"width": "50%",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"padding": "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('customer_daily_chart.ui')}}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"css": "card",
|
|
||||||
"width": "50%",
|
|
||||||
"borderRadius": "12px",
|
|
||||||
"padding": "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('customer_monthly_chart.ui')}}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
120
wwwroot/customer_users_table.ui
Normal file
120
wwwroot/customer_users_table.ui
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "card",
|
||||||
|
"width": "100%",
|
||||||
|
"borderRadius": "12px",
|
||||||
|
"padding": "20px",
|
||||||
|
"marginBottom": "20px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"alignItems": "center",
|
||||||
|
"marginBottom": "16px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Title4",
|
||||||
|
"options": {
|
||||||
|
"fontWeight": "600",
|
||||||
|
"otext": "按用户统计",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Filler"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"gap": "20px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "今日",
|
||||||
|
"i18n": true,
|
||||||
|
"fontSize": "14px",
|
||||||
|
"fontWeight": "600",
|
||||||
|
"marginBottom": "8px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"data_url": "{{entire_url('api/customer_users_today.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "auto",
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [],
|
||||||
|
"cwidth": {}
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{"name": "user_name", "title": "用户", "type": "str", "uitype": "str", "label": "用户", "cwidth": 20},
|
||||||
|
{"name": "call_cnt", "title": "调用次数", "type": "int", "uitype": "int", "label": "调用次数", "cwidth": 12},
|
||||||
|
{"name": "total_amount", "title": "金额", "type": "float", "uitype": "float", "label": "金额", "cwidth": 12}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "本月",
|
||||||
|
"i18n": true,
|
||||||
|
"fontSize": "14px",
|
||||||
|
"fontWeight": "600",
|
||||||
|
"marginBottom": "8px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"data_url": "{{entire_url('api/customer_users_month.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "auto",
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [],
|
||||||
|
"cwidth": {}
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{"name": "user_name", "title": "用户", "type": "str", "uitype": "str", "label": "用户", "cwidth": 20},
|
||||||
|
{"name": "call_cnt", "title": "调用次数", "type": "int", "uitype": "int", "label": "调用次数", "cwidth": 12},
|
||||||
|
{"name": "total_amount", "title": "金额", "type": "float", "uitype": "float", "label": "金额", "cwidth": 12}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user