fix: 用量查看优化
This commit is contained in:
@@ -12,7 +12,7 @@ import {
|
||||
} from 'echarts/components';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { getLast7DaysTokenUsage, getModelTokenUsage, getSelectableTokenInfo, getLast24HoursTokenUsage, getTodayModelUsage } from '@/api';
|
||||
import { getLast7DaysTokenUsage, getLast24HoursTokenUsage, getModelTokenUsage, getSelectableTokenInfo, getTodayModelUsage } from '@/api';
|
||||
|
||||
// 注册必要的组件
|
||||
echarts.use([
|
||||
@@ -93,11 +93,31 @@ const hourlyModels = computed(() => {
|
||||
// 计算属性:模型颜色映射(保持一致性)
|
||||
const modelColors = computed(() => {
|
||||
const baseColors = [
|
||||
'#3a4de9', '#6a5acd', '#9370db', '#8a2be2', '#9932cc',
|
||||
'#ba55d3', '#da70d6', '#ee82ee', '#dda0dd', '#ff00ff',
|
||||
'#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe',
|
||||
'#00f2fe', '#43e97b', '#38f9d7', '#fa709a', '#fee140',
|
||||
'#4361ee', '#3a0ca3', '#7209b7', '#f72585', '#4cc9f0',
|
||||
'#3a4de9',
|
||||
'#6a5acd',
|
||||
'#9370db',
|
||||
'#8a2be2',
|
||||
'#9932cc',
|
||||
'#ba55d3',
|
||||
'#da70d6',
|
||||
'#ee82ee',
|
||||
'#dda0dd',
|
||||
'#ff00ff',
|
||||
'#667eea',
|
||||
'#764ba2',
|
||||
'#f093fb',
|
||||
'#f5576c',
|
||||
'#4facfe',
|
||||
'#00f2fe',
|
||||
'#43e97b',
|
||||
'#38f9d7',
|
||||
'#fa709a',
|
||||
'#fee140',
|
||||
'#4361ee',
|
||||
'#3a0ca3',
|
||||
'#7209b7',
|
||||
'#f72585',
|
||||
'#4cc9f0',
|
||||
];
|
||||
const colorMap: Record<string, string> = {};
|
||||
|
||||
@@ -661,7 +681,7 @@ function updateHourlyBarChart() {
|
||||
return;
|
||||
}
|
||||
|
||||
const hours = hourlyUsageData.value.map(item => {
|
||||
const hours = hourlyUsageData.value.map((item) => {
|
||||
const date = new Date(item.hour);
|
||||
return `${date.getHours().toString().padStart(2, '0')}:00`;
|
||||
});
|
||||
@@ -706,7 +726,7 @@ function updateHourlyBarChart() {
|
||||
|
||||
// 构建每个模型的数据系列(并排柱状图)
|
||||
const series = hourlyModels.value.map(({ modelId }, index) => {
|
||||
const data = hourlyUsageData.value.map(hour => {
|
||||
const data = hourlyUsageData.value.map((hour) => {
|
||||
const modelData = hour.modelBreakdown?.find((m: any) => m.modelId === modelId);
|
||||
return modelData?.tokens || 0;
|
||||
});
|
||||
@@ -827,7 +847,7 @@ function updateHourlyBarChart() {
|
||||
},
|
||||
},
|
||||
toolbox: {
|
||||
show: !isMobile,
|
||||
show: true, // 强制显示工具箱
|
||||
feature: {
|
||||
dataZoom: {
|
||||
yAxisIndex: 'none',
|
||||
@@ -855,10 +875,10 @@ function updateHourlyBarChart() {
|
||||
},
|
||||
right: 15,
|
||||
top: 5,
|
||||
itemSize: 14,
|
||||
itemSize: 18,
|
||||
iconStyle: {
|
||||
borderColor: '#667eea',
|
||||
borderWidth: 1.5,
|
||||
borderWidth: 2,
|
||||
},
|
||||
emphasis: {
|
||||
iconStyle: {
|
||||
@@ -876,26 +896,6 @@ function updateHourlyBarChart() {
|
||||
},
|
||||
},
|
||||
},
|
||||
// 区域选框缩放配置
|
||||
brush: {
|
||||
id: 'brush',
|
||||
xAxisIndex: 0,
|
||||
link: ['x'],
|
||||
transform: {
|
||||
type: 'bar',
|
||||
},
|
||||
throttleType: 'debounce',
|
||||
throttleDelay: 300,
|
||||
removeOnClick: true,
|
||||
brushLink: 'all',
|
||||
brushType: false,
|
||||
inBrush: {
|
||||
opacity: 1,
|
||||
},
|
||||
outOfBrush: {
|
||||
opacity: 0.3,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
type: hourlyModels.value.length > 8 || isMobile ? 'scroll' : 'plain',
|
||||
@@ -928,12 +928,12 @@ function updateHourlyBarChart() {
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
show: !isMobile,
|
||||
show: true, // 强制显示滑动条
|
||||
start: hourlyUsageData.value.length > 12 ? 100 - Math.round((12 / hourlyUsageData.value.length) * 100) : 80,
|
||||
end: 100,
|
||||
xAxisIndex: [0],
|
||||
bottom: '3%',
|
||||
height: 18,
|
||||
height: 20,
|
||||
borderColor: 'transparent',
|
||||
fillerColor: 'rgba(102, 126, 234, 0.2)',
|
||||
handleStyle: {
|
||||
@@ -954,7 +954,7 @@ function updateHourlyBarChart() {
|
||||
moveOnMouseWheel: false,
|
||||
},
|
||||
{
|
||||
show: !isMobile && maxModelsPerHour > 3,
|
||||
show: true, // 强制显示Y轴缩放条
|
||||
yAxisIndex: [0],
|
||||
filterMode: 'empty',
|
||||
width: 28,
|
||||
@@ -977,7 +977,7 @@ function updateHourlyBarChart() {
|
||||
throttleDelay: 300,
|
||||
removeOnClick: true,
|
||||
brushLink: 'all',
|
||||
brushType: false,
|
||||
brushType: false, // 默认不启用刷子,通过工具箱激活
|
||||
inBrush: {
|
||||
opacity: 1,
|
||||
},
|
||||
@@ -1174,9 +1174,15 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
<div class="today-model-cards">
|
||||
<div v-if="todayModelUsageData.length === 0" class="empty-state">
|
||||
<div class="empty-icon">📊</div>
|
||||
<div class="empty-text">暂无数据</div>
|
||||
<div class="empty-hint">今日暂无模型使用记录</div>
|
||||
<div class="empty-icon">
|
||||
📊
|
||||
</div>
|
||||
<div class="empty-text">
|
||||
暂无数据
|
||||
</div>
|
||||
<div class="empty-hint">
|
||||
今日暂无模型使用记录
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="model-cards-grid">
|
||||
<div
|
||||
@@ -1193,13 +1199,15 @@ onBeforeUnmount(() => {
|
||||
:alt="item.modelId"
|
||||
class="model-logo"
|
||||
@error="(e) => { (e.target as HTMLImageElement).style.display = 'none'; (e.target as HTMLImageElement).nextElementSibling?.classList.remove('fallback-icon'); }"
|
||||
/>
|
||||
>
|
||||
<div v-else class="model-logo-fallback" :style="{ background: modelColors[item.modelId] || '#667eea' }">
|
||||
{{ item.modelId.charAt(0).toUpperCase() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="model-info">
|
||||
<div class="model-name" :title="item.modelId">{{ item.modelId }}</div>
|
||||
<div class="model-name" :title="item.modelId">
|
||||
{{ item.modelId }}
|
||||
</div>
|
||||
<div class="model-usage-count">
|
||||
<el-icon><i-ep-data-analysis /></el-icon>
|
||||
使用 {{ item.usageCount }} 次
|
||||
|
||||
Reference in New Issue
Block a user