848f804169
- FastAPI 后端 + Vue 3 前端 - Docker Compose 一键部署 - Casdoor OAuth 认证集成 - LogHive 集中式日志 - 设备批量 CSV 导入/导出 - WebSocket 实时状态推送 - 企业微信告警通知 - fping 高性能并发 Ping 检测 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
112 lines
3.3 KiB
Vue
112 lines
3.3 KiB
Vue
<template>
|
||
<div class="settings-page">
|
||
<!-- 用户管理 -->
|
||
<el-card shadow="hover">
|
||
<template #header>
|
||
<span>用户管理</span>
|
||
</template>
|
||
<el-table :data="users" stripe v-loading="loading">
|
||
<el-table-column prop="username" label="用户名" width="140" />
|
||
<el-table-column prop="display_name" label="显示名称" width="140" />
|
||
<el-table-column prop="role" label="角色" width="100">
|
||
<template #default="{ row }">
|
||
<el-tag :type="row.role === 'admin' ? 'danger' : 'info'" size="small">
|
||
{{ row.role === 'admin' ? '管理员' : '查看者' }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="last_login_at" label="最后登录" width="160">
|
||
<template #default="{ row }">
|
||
{{ row.last_login_at ? dayjs(row.last_login_at).format('YYYY-MM-DD HH:mm') : '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="160">
|
||
<template #default="{ row }">
|
||
<el-button
|
||
text
|
||
type="primary"
|
||
size="small"
|
||
@click="toggleRole(row)"
|
||
:disabled="row.id === currentUserId"
|
||
>
|
||
{{ row.role === 'admin' ? '设为查看者' : '设为管理员' }}
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
|
||
<!-- 系统配置 -->
|
||
<el-card shadow="hover" style="margin-top: 20px">
|
||
<template #header>
|
||
<div class="card-header">
|
||
<span>数据保留设置</span>
|
||
</div>
|
||
</template>
|
||
<el-form label-width="150px">
|
||
<el-form-item label="Ping 记录保留">
|
||
<el-input-number v-model="pingRetention" :min="7" :max="365" /> 天
|
||
</el-form-item>
|
||
<el-form-item label="告警记录保留">
|
||
<el-input-number v-model="alertRetention" :min="30" :max="730" /> 天
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="saveConfig">保存设置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import { useAppStore } from '@/stores/app'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import dayjs from 'dayjs'
|
||
import api from '@/api'
|
||
|
||
const store = useAppStore()
|
||
const currentUserId = computed(() => store.user?.id)
|
||
|
||
const users = ref([])
|
||
const loading = ref(false)
|
||
const pingRetention = ref(90)
|
||
const alertRetention = ref(365)
|
||
|
||
onMounted(() => {
|
||
fetchUsers()
|
||
})
|
||
|
||
async function fetchUsers() {
|
||
loading.value = true
|
||
try {
|
||
users.value = await api.get('/users')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
async function toggleRole(user) {
|
||
const newRole = user.role === 'admin' ? 'viewer' : 'admin'
|
||
await ElMessageBox.confirm(
|
||
`确定将「${user.display_name || user.username}」${newRole === 'admin' ? '设为管理员' : '降为查看者'}?`,
|
||
'提示'
|
||
)
|
||
await api.put(`/users/${user.id}/role`, { role: newRole })
|
||
ElMessage.success('已更新')
|
||
fetchUsers()
|
||
}
|
||
|
||
function saveConfig() {
|
||
ElMessage.success('设置已保存(需要在后端更新配置)')
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
</style>
|