去除趋势数据

This commit is contained in:
liuwei
2025-03-26 14:39:19 +08:00
parent 3372b156bd
commit 09a259932d

View File

@@ -45,7 +45,7 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="280">
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button
size="mini"
@@ -59,12 +59,6 @@
@click="toggleRobotStatus(scope.row)">
{% raw %}{{ scope.row.robot_status === 'enabled' ? '关闭' : '启用' }}{% endraw %}
</el-button>
<el-button
size="mini"
type="info"
@click="viewMessageTrend(scope.row)">
消息趋势
</el-button>
</template>
</el-table-column>
</el-table>
@@ -136,82 +130,6 @@
<el-button type="primary" @click="submitAddGroup">确定</el-button>
</span>
</el-dialog>
<!-- 群组消息趋势图对话框 -->
<el-dialog
:title="currentGroupName + ' 消息趋势'"
:visible.sync="trendDialogVisible"
width="70%"
@opened="onTrendDialogOpened"
destroy-on-close>
<div v-if="trendLoading" style="text-align: center; padding: 20px;">
<i class="el-icon-loading"></i>
<p>加载中...</p>
</div>
<div v-else>
<div class="chart-container">
<h3>消息数量趋势</h3>
<!-- 添加 v-if 确保 trendData 存在 -->
<div v-if="trendData && 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>
<!-- 统计摘要 - 同样添加 v-if 确保 trendData 存在 -->
<div v-if="trendData && 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">
<el-radio-button :label="7">最近7天</el-radio-button>
<el-radio-button :label="14">最近14天</el-radio-button>
<el-radio-button :label="30">最近30天</el-radio-button>
</el-radio-group>
</div>
</div>
</el-dialog>
</div>
{% endblock %}
@@ -239,16 +157,7 @@
{ required: true, message: '请输入群组ID', trigger: 'blur' },
{ pattern: /^\S+$/, message: '群组ID不能包含空格', trigger: 'blur' }
]
},
// 趋势图相关数据
trendDialogVisible: false,
trendLoading: false,
trendDays: 7,
trendData: {
dates: [],
counts: []
},
charts: {} // 保留charts对象以防其他地方还在使用
}
}
},
computed: {
@@ -259,33 +168,6 @@
(group.group_id && group.group_id.toLowerCase().includes(query)) ||
(group.group_name && group.group_name.toLowerCase().includes(query))
);
},
// 计算属性用于趋势数据
totalMessages() {
if (!this.trendData || !this.trendData.counts) return 0;
return this.trendData.counts.reduce((sum, count) => sum + parseInt(count || 0), 0);
},
avgMessages() {
if (!this.trendData || !this.trendData.dates || this.trendData.dates.length === 0) return 0;
return (this.totalMessages / this.trendData.dates.length).toFixed(2);
},
maxMessages() {
if (!this.trendData || !this.trendData.counts || this.trendData.counts.length === 0) return 0;
return Math.max(...this.trendData.counts.map(c => parseInt(c || 0)));
},
minMessages() {
if (!this.trendData || !this.trendData.counts || this.trendData.counts.length === 0) return 0;
return Math.min(...this.trendData.counts.map(c => parseInt(c || 0)));
},
maxDay() {
if (!this.trendData || !this.trendData.counts || !this.trendData.dates) return '';
const maxIndex = this.trendData.counts.indexOf(this.maxMessages.toString());
return maxIndex >= 0 ? this.trendData.dates[maxIndex] : '';
},
minDay() {
if (!this.trendData || !this.trendData.counts || !this.trendData.dates) return '';
const minIndex = this.trendData.counts.indexOf(this.minMessages.toString());
return minIndex >= 0 ? this.trendData.dates[minIndex] : '';
}
},
mounted() {
@@ -495,87 +377,8 @@
this.$message.error('批量移除失败: ' + error.message);
});
}).catch(() => {});
},
// 查看消息趋势
viewMessageTrend(group) {
this.currentGroupId = group.group_id;
this.currentGroupName = group.group_name || group.group_id;
this.trendDialogVisible = true;
},
// 对话框打开后的回调
onTrendDialogOpened() {
console.log('对话框已打开');
this.$nextTick(() => {
this.loadMessageTrend();
});
},
loadMessageTrend() {
this.trendLoading = true;
axios.get(`/api/robot/group/${this.currentGroupId}/message_trend?days=${this.trendDays}`)
.then(response => {
if (response.data.success) {
// 直接更新数据让Vue的响应式系统处理渲染
this.trendData = response.data.data || { dates: [], counts: [] };
this.trendLoading = false;
} else {
this.$message.error('加载消息趋势失败');
// 设置默认值
this.trendData = { dates: [], counts: [] };
this.trendLoading = false;
}
})
.catch(error => {
console.error('加载消息趋势失败:', error);
this.$message.error('加载消息趋势失败: ' + error.message);
// 设置默认值
this.trendData = { dates: [], counts: [] };
this.trendLoading = false;
});
},
// 计算百分比的方法
getPercentage(index) {
if (!this.trendData || !this.trendData.counts || !Array.isArray(this.trendData.counts)) return 0;
if (index < 0 || index >= this.trendData.counts.length) return 0;
const count = parseInt(this.trendData.counts[index] || 0);
return this.totalMessages > 0 ?
((count / this.totalMessages) * 100).toFixed(2) : 0;
},
// 确保在打开对话框时重置 trendData
viewMessageTrend(group) {
this.currentGroupId = group.group_id;
this.currentGroupName = group.group_name || group.group_id;
// 重置 trendData 为默认值
this.trendData = { dates: [], counts: [] };
this.trendDialogVisible = true;
}
// ... 其他方法保持不变 ...
}
});
</script>
{% endblock %}
{% block styles %}
<style>
.chart-container {
margin-bottom: 20px;
padding: 10px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.chart-container h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 16px;
color: #606266;
}
</style>
{% endblock %}