调整为表格~~~

This commit is contained in:
liuwei
2025-03-26 14:30:59 +08:00
parent 85a88bb79a
commit afb1ae2899

View File

@@ -151,8 +151,57 @@
<div v-else>
<div class="chart-container">
<h3>消息数量趋势</h3>
<!-- 直接在Vue模板中创建图表容器 -->
<div ref="trendChartContainer" style="width: 100%; height: 300px;"></div>
<!-- 使用Vue的条件渲染和循环来显示表格 -->
<div v-if="trendData.dates && trendData.dates.length > 0">
<table class="el-table" style="width: 100%;">
<thead>
<tr>
<th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">日期</th>
<th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">消息数量</th>
</tr>
</thead>
<tbody>
<tr v-for="(date, index) in trendData.dates" :key="index">
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">{{ date }}</td>
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">
{{ trendData.counts[index] }}
<span style="color: #909399; font-size: 12px;">({{ getPercentage(index) }}%)</span>
<div style="width: 100%; height: 6px; background-color: #f0f0f0; margin-top: 5px; border-radius: 3px;">
<div style="height: 100%; background-color: #409EFF; border-radius: 3px;" :style="{ width: getPercentage(index) + '%' }"></div>
</div>
</td>
</tr>
<tr>
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5; font-weight: bold;">总计</td>
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5; font-weight: bold;">{{ totalMessages }}</td>
</tr>
</tbody>
</table>
</div>
<div v-else style="text-align: center; padding: 20px;">暂无数据</div>
<!-- 统计摘要 -->
<div v-if="trendData.dates && trendData.dates.length > 0" style="margin-top: 20px; padding: 15px; background-color: #f5f7fa; border-radius: 4px;">
<h4 style="margin: 0 0 10px 0;">统计摘要</h4>
<div style="display: flex; flex-wrap: wrap; gap: 15px;">
<div style="flex: 1; min-width: 150px;">
<div style="font-size: 12px; color: #909399;">总消息数</div>
<div style="font-size: 18px; font-weight: bold; color: #303133;">{{ totalMessages }}</div>
</div>
<div style="flex: 1; min-width: 150px;">
<div style="font-size: 12px; color: #909399;">日均消息数</div>
<div style="font-size: 18px; font-weight: bold; color: #303133;">{{ avgMessages }}</div>
</div>
<div style="flex: 1; min-width: 150px;">
<div style="font-size: 12px; color: #909399;">最高消息日</div>
<div style="font-size: 18px; font-weight: bold; color: #303133;">{{ maxDay }} ({{ maxMessages }})</div>
</div>
<div style="flex: 1; min-width: 150px;">
<div style="font-size: 12px; color: #909399;">最低消息日</div>
<div style="font-size: 18px; font-weight: bold; color: #303133;">{{ minDay }} ({{ minMessages }})</div>
</div>
</div>
</div>
</div>
<div style="margin-top: 20px; text-align: center;">
<el-radio-group v-model="trendDays" @change="loadMessageTrend">
@@ -195,7 +244,10 @@
trendDialogVisible: false,
trendLoading: false,
trendDays: 7,
charts: {} // 使用charts对象存储图表实例
trendData: {
dates: [],
counts: []
}
}
},
computed: {
@@ -206,6 +258,30 @@
(group.group_id && group.group_id.toLowerCase().includes(query)) ||
(group.group_name && group.group_name.toLowerCase().includes(query))
);
},
// 计算属性用于趋势数据
totalMessages() {
return this.trendData.counts.reduce((sum, count) => sum + parseInt(count || 0), 0);
},
avgMessages() {
return this.trendData.dates.length > 0 ?
(this.totalMessages / this.trendData.dates.length).toFixed(2) : 0;
},
maxMessages() {
return this.trendData.counts.length > 0 ?
Math.max(...this.trendData.counts.map(c => parseInt(c || 0))) : 0;
},
minMessages() {
return this.trendData.counts.length > 0 ?
Math.min(...this.trendData.counts.map(c => parseInt(c || 0))) : 0;
},
maxDay() {
const maxIndex = this.trendData.counts.indexOf(this.maxMessages.toString());
return maxIndex >= 0 ? this.trendData.dates[maxIndex] : '';
},
minDay() {
const minIndex = this.trendData.counts.indexOf(this.minMessages.toString());
return minIndex >= 0 ? this.trendData.dates[minIndex] : '';
}
},
mounted() {
@@ -426,8 +502,9 @@
// 对话框打开后的回调
onTrendDialogOpened() {
console.log('对话框已打开');
// 直接加载数据,不使用延迟
this.loadMessageTrend();
this.$nextTick(() => {
this.loadMessageTrend();
});
},
loadMessageTrend() {
@@ -436,8 +513,8 @@
axios.get(`/api/robot/group/${this.currentGroupId}/message_trend?days=${this.trendDays}`)
.then(response => {
if (response.data.success) {
// 直接渲染表格显示数据
this.renderTrendTable(response.data.data);
// 直接更新数据让Vue的响应式系统处理渲染
this.trendData = response.data.data || { dates: [], counts: [] };
this.trendLoading = false;
} else {
this.$message.error('加载消息趋势失败');
@@ -451,126 +528,14 @@
});
},
renderTrendTable(data) {
try {
console.log('开始渲染趋势数据');
// 获取容器元素
const container = this.$refs.trendChartContainer;
if (!container) {
console.error('找不到图表容器');
this.$message.error('无法找到图表容器,请尝试重新打开对话框');
return;
}
// 准备数据
const labels = data.dates || [];
const messageData = (data.counts || []).map(count => parseInt(count) || 0);
if (labels.length === 0) {
container.innerHTML = '<div style="text-align: center; padding: 20px;">暂无数据</div>';
return;
}
// 销毁之前的图表实例(如果存在)
if (this.charts.trendChart) {
this.charts.trendChart.destroy();
}
// 创建canvas元素
container.innerHTML = '<canvas id="messageChart" width="100%" height="300"></canvas>';
const ctx = document.getElementById('messageChart').getContext('2d');
// 使用Chart.js创建图表
this.charts.trendChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: '消息数量',
data: messageData,
backgroundColor: 'rgba(75, 192, 192, 0.5)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: '消息数量'
}
},
x: {
title: {
display: true,
text: '日期'
}
}
},
plugins: {
title: {
display: true,
text: '群组消息数量趋势',
font: {
size: 16
}
},
tooltip: {
callbacks: {
label: function(context) {
return `消息数量: ${context.raw}`;
}
}
}
}
}
});
// 添加表格显示详细数据
let tableHtml = `
<div style="margin-top: 20px;">
<h4 style="margin: 10px 0;">详细数据</h4>
<table class="el-table" style="width: 100%;">
<thead>
<tr>
<th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">日期</th>
<th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">消息数量</th>
</tr>
</thead>
<tbody>
`;
for (let i = 0; i < labels.length; i++) {
tableHtml += `
<tr>
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">${labels[i]}</td>
<td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">${messageData[i]}</td>
</tr>
`;
}
tableHtml += `
</tbody>
</table>
</div>
`;
// 在图表下方添加表格
const tableContainer = document.createElement('div');
tableContainer.innerHTML = tableHtml;
container.parentNode.insertBefore(tableContainer, container.nextSibling);
} catch (error) {
console.error('渲染趋势数据出错:', error);
this.$message.error('渲染趋势数据出错: ' + error.message);
}
// 计算百分比的方法
getPercentage(index) {
const count = parseInt(this.trendData.counts[index] || 0);
return this.totalMessages > 0 ?
((count / this.totalMessages) * 100).toFixed(2) : 0;
}
// ... 保留其他方法 ...
}
});
</script>