feat(dashboard): unify global UI theme across all admin templates

This commit is contained in:
liuwei
2026-04-15 17:00:15 +08:00
parent ee5c1ebadc
commit cb8adc40ce
19 changed files with 808 additions and 379 deletions

View File

@@ -28,9 +28,9 @@
{% block scripts %}
<script>
new Vue({ el:'#app', mixins:[baseApp], data(){ return { pluginStats:[], pluginTrendVisible:false, selectedPlugin:null } }, computed:{ totalCalls(){ return this.pluginStats.reduce((s,i)=>s+(parseInt(i.total_calls)||0),0); }, averageSuccessRate(){ if(!this.pluginStats.length) return '0.00'; const sum=this.pluginStats.reduce((s,i)=>s+(parseInt(i.total_calls)>0?((parseInt(i.success_calls)/parseInt(i.total_calls))*100):100),0); return (sum/this.pluginStats.length).toFixed(2); } }, mounted(){ this.currentView='2'; this.loadData(); }, methods:{ loadData(){ this.loadPluginStats(parseInt(this.timeRange)); }, loadPluginStats(days){ axios.get(`/api/plugin_stats?days=${days}`).then(r=>{ if(r.data.success) this.pluginStats=r.data.data||[]; }).catch(e=>{ console.error('加载插件统计数据出错:',e); this.$message.error('加载插件统计数据出错'); }); }, viewPluginTrend(plugin){ this.selectedPlugin=plugin; this.pluginTrendVisible=true; const days=parseInt(this.timeRange); axios.get(`/api/plugin_trend?days=${days}&plugin_name=${plugin.plugin_name}`).then(r=>{ if(r.data.success){ const trendData=r.data.data||[]; this.$nextTick(()=>this.renderPluginTrendChart(trendData, plugin.plugin_name)); } }).catch(e=>{ console.error('加载插件趋势数据出错:',e); this.$message.error('加载插件趋势数据出错'); }); }, renderPluginTrendChart(trendData, pluginName){ const ctx=document.getElementById('pluginTrendChart').getContext('2d'); if(this.charts&&this.charts.pluginTrendChart)this.charts.pluginTrendChart.destroy(); if(!this.charts)this.charts={}; const labels=trendData.map(i=>i.date||i.stat_date); const totalData=trendData.map(i=>parseInt(i.total_calls)||0); const successData=trendData.map(i=>parseInt(i.success_calls)||0); const failedData=trendData.map(i=>parseInt(i.failed_calls)||0); this.charts.pluginTrendChart=new Chart(ctx,{ type:'line', data:{ labels, datasets:[ {label:`${pluginName} 总调用`,data:totalData,fill:false,backgroundColor:'rgba(79,70,229,.2)',borderColor:'rgba(79,70,229,1)',tension:.28,borderWidth:3,pointRadius:2},{label:`${pluginName} 成功调用`,data:successData,fill:false,backgroundColor:'rgba(16,185,129,.2)',borderColor:'rgba(16,185,129,1)',tension:.28,borderWidth:3,pointRadius:2},{label:`${pluginName} 失败调用`,data:failedData,fill:false,backgroundColor:'rgba(239,68,68,.2)',borderColor:'rgba(239,68,68,1)',tension:.28,borderWidth:3,pointRadius:2}]}, options:{ responsive:true, scales:{ y:{beginAtZero:true,grid:{color:'rgba(148,163,184,.12)'}}, x:{grid:{display:false}} } } }); } } });
new Vue({ el:'#app', mixins:[baseApp], data(){ return { pluginStats:[], pluginTrendVisible:false, selectedPlugin:null } }, computed:{ totalCalls(){ return this.pluginStats.reduce((s,i)=>s+(parseInt(i.total_calls)||0),0); }, averageSuccessRate(){ if(!this.pluginStats.length) return '0.00'; const sum=this.pluginStats.reduce((s,i)=>s+(parseInt(i.total_calls)>0?((parseInt(i.success_calls)/parseInt(i.total_calls))*100):100),0); return (sum/this.pluginStats.length).toFixed(2); } }, mounted(){ this.currentView='2'; this.loadData(); }, methods:{ loadData(){ this.loadPluginStats(parseInt(this.timeRange)); }, loadPluginStats(days){ axios.get(`/api/plugin_stats?days=${days}`).then(r=>{ if(r.data.success) this.pluginStats=r.data.data||[]; }).catch(e=>{ console.error('加载插件统计数据出错:',e); this.$message.error('加载插件统计数据出错'); }); }, viewPluginTrend(plugin){ this.selectedPlugin=plugin; this.pluginTrendVisible=true; const days=parseInt(this.timeRange); axios.get(`/api/plugin_trend?days=${days}&plugin_name=${plugin.plugin_name}`).then(r=>{ if(r.data.success){ const trendData=r.data.data||[]; this.$nextTick(()=>this.renderPluginTrendChart(trendData, plugin.plugin_name)); } }).catch(e=>{ console.error('加载插件趋势数据出错:',e); this.$message.error('加载插件趋势数据出错'); }); }, renderPluginTrendChart(trendData, pluginName){ const ctx=document.getElementById('pluginTrendChart').getContext('2d'); if(this.charts&&this.charts.pluginTrendChart)this.charts.pluginTrendChart.destroy(); if(!this.charts)this.charts={}; const labels=trendData.map(i=>i.date||i.stat_date); const totalData=trendData.map(i=>parseInt(i.total_calls)||0); const successData=trendData.map(i=>parseInt(i.success_calls)||0); const failedData=trendData.map(i=>parseInt(i.failed_calls)||0); this.charts.pluginTrendChart=new Chart(ctx,{ type:'line', data:{ labels, datasets:[ {label:`${pluginName} 总调用`,data:totalData,fill:false,backgroundColor:'rgba(15,118,110,.2)',borderColor:'rgba(15,118,110,1)',tension:.28,borderWidth:3,pointRadius:2},{label:`${pluginName} 成功调用`,data:successData,fill:false,backgroundColor:'rgba(16,185,129,.2)',borderColor:'rgba(16,185,129,1)',tension:.28,borderWidth:3,pointRadius:2},{label:`${pluginName} 失败调用`,data:failedData,fill:false,backgroundColor:'rgba(239,68,68,.2)',borderColor:'rgba(239,68,68,1)',tension:.28,borderWidth:3,pointRadius:2}]}, options:{ responsive:true, scales:{ y:{beginAtZero:true,grid:{color:'rgba(101,121,113,.12)'}}, x:{grid:{display:false}} } } }); } } });
</script>
<style>
.page-shell{display:flex;flex-direction:column;gap:16px}.page-hero{padding:24px 26px;border-radius:24px;background:linear-gradient(135deg, rgba(79,70,229,.10), rgba(59,130,246,.08), rgba(255,255,255,.9));border:1px solid rgba(148,163,184,.16);box-shadow:0 18px 40px rgba(15,23,42,.06)}.page-eyebrow{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:#6366f1;font-weight:700;margin-bottom:8px}.page-hero-copy h1{font-size:30px;line-height:1.1;margin-bottom:10px;color:#0f172a}.page-hero-copy p{color:#64748b;font-size:14px}.overview-grid .el-col{margin-bottom:16px}.overview-card{min-height:112px}.overview-card--primary{background:linear-gradient(180deg, rgba(79,70,229,.10), rgba(255,255,255,.94)) !important}.overview-card--soft{background:linear-gradient(180deg, rgba(59,130,246,.08), rgba(255,255,255,.94)) !important}.overview-label{font-size:13px;color:#64748b;margin-bottom:14px}.overview-value{font-size:30px;font-weight:700;color:#0f172a;margin-bottom:10px}.overview-note{font-size:12px;color:#94a3b8}.workspace-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.workspace-header h3{font-size:18px;margin-bottom:4px}.workspace-header p{font-size:13px;color:#64748b}.entity-cell{display:flex;align-items:center;gap:12px}.entity-badge{width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:rgba(79,70,229,.10);color:#4f46e5;font-size:12px;font-weight:700;flex-shrink:0}.entity-title{font-size:14px;font-weight:600;color:#0f172a}.entity-subtitle{margin-top:4px;font-size:12px;color:#94a3b8}.chart-shell{padding:16px;border-radius:18px;background:linear-gradient(180deg, rgba(248,250,252,.78), rgba(255,255,255,.96));border:1px solid rgba(148,163,184,.12)}.chart-heading{margin-bottom:12px;font-size:14px;font-weight:600;color:#334155}
.page-shell{display:flex;flex-direction:column;gap:16px}.page-hero{padding:24px 26px;border-radius:24px;background:linear-gradient(135deg, rgba(15,118,110,.10), rgba(14,165,233,.08), rgba(255,255,255,.9));border:1px solid rgba(101,121,113,.16);box-shadow:0 18px 40px rgba(21,33,27,.06)}.page-eyebrow{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:#0b5e57;font-weight:700;margin-bottom:8px}.page-hero-copy h1{font-size:30px;line-height:1.1;margin-bottom:10px;color:#15211b}.page-hero-copy p{color:#4f6258;font-size:14px}.overview-grid .el-col{margin-bottom:16px}.overview-card{min-height:112px}.overview-card--primary{background:linear-gradient(180deg, rgba(15,118,110,.10), rgba(255,255,255,.94)) !important}.overview-card--soft{background:linear-gradient(180deg, rgba(14,165,233,.08), rgba(255,255,255,.94)) !important}.overview-label{font-size:13px;color:#4f6258;margin-bottom:14px}.overview-value{font-size:30px;font-weight:700;color:#15211b;margin-bottom:10px}.overview-note{font-size:12px;color:#74897f}.workspace-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.workspace-header h3{font-size:18px;margin-bottom:4px}.workspace-header p{font-size:13px;color:#4f6258}.entity-cell{display:flex;align-items:center;gap:12px}.entity-badge{width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:rgba(15,118,110,.10);color:#0f766e;font-size:12px;font-weight:700;flex-shrink:0}.entity-title{font-size:14px;font-weight:600;color:#15211b}.entity-subtitle{margin-top:4px;font-size:12px;color:#74897f}.chart-shell{padding:16px;border-radius:18px;background:linear-gradient(180deg, rgba(247,251,248,.78), rgba(255,255,255,.96));border:1px solid rgba(101,121,113,.12)}.chart-heading{margin-bottom:12px;font-size:14px;font-weight:600;color:#27443a}
</style>
{% endblock %}