Phase 1-2 deliverables: - shell.ui: Global layout framework (topbar + collapsible sidebar + main content) - shell_theme.css: Dark/light theme CSS custom properties system - shell_theme.js: Theme toggle + sidebar collapse with localStorage persistence - global_menu.ui: Unified module navigation menu with RBAC visibility - index.ui: Redesigned dashboard homepage with modern stat cards + quick links - Stat card widgets: today_usage, today_amount, total_users, concurrent, errors - chart_top_models.ui + api/top_models.dspy: ChartBar with data_url pattern - table_top_users_amount.ui: Jinja2-rendered user ranking table - build.sh: Added .css file linking support Design system: - Dark theme (default): slate color palette (#0B1120, #111827, #1E293B) - Light theme: clean white palette with matching structure - Theme persisted in localStorage, toggled via topbar button - Sidebar collapsible with icon-only mode, state persisted in localStorage - Responsive stat cards with hover effects and trend indicators - Quick link cards for model management, users, knowledge base, errors
58 lines
2.8 KiB
XML
58 lines
2.8 KiB
XML
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"bgcolor": "#FFFFFF",
|
||
"padding": "20px",
|
||
"borderRadius": "8px",
|
||
"minHeight": "280px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Text",
|
||
"options": {
|
||
"text": "用户金额 TOP 5(今日)",
|
||
"fontSize": "16px",
|
||
"fontWeight": "bold",
|
||
"color": "#333",
|
||
"marginBottom": "12px"
|
||
}
|
||
},
|
||
{% set rows = get_top_users_by_amount(request) %}
|
||
{% if rows %}
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {"spacing": "8px"},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {"bgcolor": "#f5f5f5", "padding": "8px 12px", "borderRadius": "4px"},
|
||
"subwidgets": [
|
||
{"widgettype": "Text", "options": {"text": "排名", "fontSize": "12px", "color": "#888", "width": "50px"}},
|
||
{"widgettype": "Text", "options": {"text": "用户", "fontSize": "12px", "color": "#888", "flex": "1"}},
|
||
{"widgettype": "Text", "options": {"text": "金额", "fontSize": "12px", "color": "#888", "width": "100px", "textAlign": "right"}},
|
||
{"widgettype": "Text", "options": {"text": "笔数", "fontSize": "12px", "color": "#888", "width": "60px", "textAlign": "right"}}
|
||
]
|
||
},
|
||
{% for item in rows %}
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {"padding": "8px 12px", "borderRadius": "4px", "bgcolor": "{% if loop.index == 1 %}#fff3e0{% elif loop.index == 2 %}#fff8e1{% elif loop.index == 3 %}#fffde7{% else %}#fafafa{% endif %}"},
|
||
"subwidgets": [
|
||
{"widgettype": "Text", "options": {"text": "{{loop.index}}", "fontSize": "13px", "color": "{% if loop.index <= 3 %}#e65100{% else %}#666{% endif %}", "width": "50px", "fontWeight": "bold"}},
|
||
{"widgettype": "Text", "options": {"text": "{{item.user_name}}", "fontSize": "13px", "color": "#333", "flex": "1"}},
|
||
{"widgettype": "Text", "options": {"text": "{{item.total_amount|round(2)}}", "fontSize": "13px", "color": "#2e7d32", "width": "100px", "textAlign": "right", "fontWeight": "bold"}},
|
||
{"widgettype": "Text", "options": {"text": "{{item.cnt}}", "fontSize": "13px", "color": "#666", "width": "60px", "textAlign": "right"}}
|
||
]
|
||
}{% if not loop.last %},{% endif %}
|
||
{% endfor %}
|
||
]
|
||
}
|
||
{% else %}
|
||
{
|
||
"widgettype": "Text",
|
||
"options": {"text": "暂无数据", "fontSize": "14px", "color": "#999", "textAlign": "center"}
|
||
}
|
||
{% endif %}
|
||
]
|
||
}
|