feat: 日志中心 + GRE协议支持 + 流量监控 + 部署脚本

- 新增日志中心功能 (api/logapi.go + Logs.vue)
- 新增GRE协议服务支持 (service/gre/)
- 新增流量监控组件 (TrafficChart.vue)
- 新增L2TP/IPSec测试用例
- 新增日志轮转服务 (logrotate.go)
- 新增部署脚本 (scripts/install.sh, uninstall.sh, service文件)
- 更新i18n国际化文件
- 优化后端API和前端路由
This commit is contained in:
opsx-tools committed 2026-07-25 08:50:34 +08:00
1 parent 7de1f70905
commit a14d9e62e6
25 files changed
+2285 -25

No files matched your search

+3 -18
View File
@@ -45,15 +45,9 @@
<el-col :xs="24" :lg="14" v-if="auth.isAdmin()">
<el-card class="page-card" shadow="never">
<template #header><b>{{ $t('settings.auditTitle') }}</b></template>
<el-table :data="logs" size="small" max-height="560" v-loading="auditLoading">
<el-table-column prop="created_at" :label="$t('common.time')" width="170">
<template #default="{ row }">{{ new Date(row.created_at).toLocaleString() }}</template>
</el-table-column>
<el-table-column prop="username" :label="$t('common.username')" width="90" />
<el-table-column prop="action" :label="$t('common.action')" width="140" />
<el-table-column prop="target" :label="$t('common.target')" show-overflow-tooltip />
<template #empty><el-empty :description="$t('settings.noAuditLogs')" /></template>
</el-table>
<el-empty :description="$t('settings.auditMigrated')">
<el-button type="primary" @click="$router.push('/logs')">{{ $t('router.logs') }}</el-button>
</el-empty>
</el-card>
</el-col>
@@ -83,8 +77,6 @@ import api, { auth } from '../api'
const { t } = useI18n()
const pwd = ref({ old_password: '', new_password: '', confirm: '' })
const pwdLoading = ref(false)
const logs = ref([])
const auditLoading = ref(false)
const mfa = ref({ enabled: false, uri: '', code: '' })
const mfaCanvas = ref(null)
const mfaLoading = ref(false)
@@ -110,13 +102,6 @@ onMounted(async () => {
const status = await api.get('/mfa/status')
mfa.value.enabled = status.data.enabled
} catch { /* ignore */ }
if (auth.isAdmin()) {
auditLoading.value = true
try {
const audit = await api.get('/audit')
logs.value = audit.data || []
} catch { /* viewer */ } finally { auditLoading.value = false }
}
})
async function setupMFA() {