Files
abot/admin/dashboard/templates/wx_logs.html
2025-12-25 15:59:37 +08:00

199 lines
6.7 KiB
HTML

{% extends "base.html" %}
{% block title %}微信日志查看{% endblock %}
{% block content %}
<div class="log-page-container">
<el-card class="log-card">
<div slot="header" class="clearfix">
<span>日志查看</span>
<el-radio-group v-model="logType" size="small" style="margin-left: 20px;" @change="loadLogs">
<el-radio-button label="info">信息日志</el-radio-button>
<el-radio-button label="error">错误日志</el-radio-button>
<el-radio-button label="debug">调试日志</el-radio-button>
</el-radio-group>
<el-select v-model="logLines" size="small" style="margin-left: 20px;" @change="loadLogs">
<el-option label="最近100行" :value="100"></el-option>
<el-option label="最近500行" :value="500"></el-option>
<el-option label="最近1000行" :value="1000"></el-option>
</el-select>
<el-select v-model="refreshInterval" size="small" style="margin-left: 20px; width: 100px;" @change="handleRefreshInterval">
<el-option label="手动" :value="0"></el-option>
<el-option label="1秒" :value="1"></el-option>
<el-option label="3秒" :value="3"></el-option>
<el-option label="5秒" :value="5"></el-option>
<el-option label="10秒" :value="10"></el-option>
<el-option label="60秒" :value="60"></el-option>
</el-select>
<el-button style="float: right; padding: 3px 0" type="text" @click="loadLogs">刷新</el-button>
</div>
<div v-loading="loading" class="log-content-wrapper">
<div v-if="logContent && logContent.length > 0" class="log-content">
<pre ref="logPre"></pre>
</div>
<div v-else class="empty-log">
<el-empty description="暂无日志内容"></el-empty>
</div>
</div>
</el-card>
</div>
{% endblock %}
{% block scripts %}
<script>
new Vue({
el: '#app',
mixins: [baseApp],
data() {
return {
loading: false,
logType: 'info',
logLines: 100,
logContent: [],
logText: '',
refreshInterval: 0,
refreshTimer: null,
currentView: '9',
showTimeRangeSelector: false,
cancelSource: null,
isAutoScroll: true
}
},
mounted() {
this.loadLogs();
this.$nextTick(() => {
const logDiv = this.$el.querySelector('.log-content');
if (logDiv) {
logDiv.addEventListener('scroll', () => {
const nearBottom = (logDiv.scrollHeight - logDiv.scrollTop - logDiv.clientHeight) < 50;
this.isAutoScroll = nearBottom;
});
}
});
},
beforeDestroy() {
this.clearRefreshTimer();
if (this.cancelSource) {
this.cancelSource.cancel('component destroyed');
this.cancelSource = null;
}
},
methods: {
loadLogs() {
this.loading = true;
if (this.cancelSource) {
this.cancelSource.cancel('new request');
}
this.cancelSource = axios.CancelToken.source();
axios.get(`/api/wx_logs`, {
params: { type: this.logType, lines: this.logLines },
headers: { 'Accept-Encoding': 'gzip' },
cancelToken: this.cancelSource.token
})
.then(response => {
if (response.data.success) {
this.logContent = response.data.data.content || [];
this.logText = this.logContent.join('\n');
this.$nextTick(() => {
const logDiv = this.$el.querySelector('.log-content');
const pre = this.$refs.logPre;
if (pre) {
pre.textContent = this.logText;
}
if (logDiv) {
if (this.isAutoScroll) {
logDiv.scrollTop = logDiv.scrollHeight;
}
}
});
} else {
this.$message.error('加载日志失败');
}
})
.catch(error => {
if (!axios.isCancel(error)) {
console.error('加载日志出错:', error);
this.$message.error('加载日志出错');
}
})
.finally(() => {
this.loading = false;
});
},
handleRefreshInterval() {
this.clearRefreshTimer();
if (this.refreshInterval > 0) {
this.refreshTimer = setInterval(() => {
this.loadLogs();
}, this.refreshInterval * 1000);
}
},
clearRefreshTimer() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
}
}
});
</script>
<style>
.log-page-container {
height: 100%;
display: flex;
flex-direction: column;
}
.log-card {
flex: 1;
display: flex;
flex-direction: column;
margin: 0;
height: 100%;
}
.el-card__body {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.log-content-wrapper {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.log-content {
flex: 1;
overflow-y: auto !important;
overflow-x: scroll !important;
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
box-sizing: border-box;
min-height: 0;
}
.log-content pre {
margin: 0;
white-space: pre;
word-break: break-all;
font-family: monospace;
line-height: 1;
}
.empty-log {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
</style>
{% endblock %}