Files
000-platform/frontend/src/views/users/index.vue
111 b89d5ddee9
Some checks failed
continuous-integration/drone/push Build is failing
feat: add admin UI frontend and complete backend APIs
- Add Vue 3 frontend with Element Plus
- Implement login, dashboard, tenant management
- Add app configuration, logs viewer, stats pages
- Add user management for admins
- Update Drone CI to build and deploy frontend
- Frontend ports: 3001 (test), 4001 (prod)
2026-01-23 15:51:37 +08:00

170 lines
5.0 KiB
Vue

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import api from '@/api'
import { useAuthStore } from '@/stores/auth'
const authStore = useAuthStore()
const loading = ref(false)
const tableData = ref([])
// 对话框
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formRef = ref(null)
const form = reactive({
username: '',
password: '',
nickname: '',
role: 'viewer'
})
const rules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
async function fetchList() {
loading.value = true
try {
const res = await api.get('/api/auth/users')
tableData.value = res.data || []
} catch (e) {
console.error(e)
} finally {
loading.value = false
}
}
function handleCreate() {
dialogTitle.value = '新建用户'
Object.assign(form, {
username: '',
password: '',
nickname: '',
role: 'viewer'
})
dialogVisible.value = true
}
async function handleSubmit() {
await formRef.value.validate()
try {
await api.post('/api/auth/users', form)
ElMessage.success('创建成功')
dialogVisible.value = false
fetchList()
} catch (e) {
// 错误已在拦截器处理
}
}
async function handleDelete(row) {
if (row.id === authStore.user?.id) {
ElMessage.warning('不能删除当前登录用户')
return
}
await ElMessageBox.confirm(`确定删除用户 "${row.username}" 吗?`, '提示', {
type: 'warning'
})
try {
await api.delete(`/api/auth/users/${row.id}`)
ElMessage.success('删除成功')
fetchList()
} catch (e) {
// 错误已在拦截器处理
}
}
function getRoleTag(role) {
const map = {
admin: { type: 'danger', text: '管理员' },
operator: { type: 'warning', text: '操作员' },
viewer: { type: 'info', text: '只读' }
}
return map[role] || { type: 'info', text: role }
}
onMounted(() => {
fetchList()
})
</script>
<template>
<div class="page-container">
<div class="page-header">
<div class="title">用户管理</div>
<el-button type="primary" @click="handleCreate">
<el-icon><Plus /></el-icon>
新建用户
</el-button>
</div>
<!-- 表格 -->
<el-table v-loading="loading" :data="tableData" style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="username" label="用户名" width="150" />
<el-table-column prop="nickname" label="昵称" width="150" />
<el-table-column prop="role" label="角色" width="120">
<template #default="{ row }">
<el-tag :type="getRoleTag(row.role).type" size="small">
{{ getRoleTag(row.role).text }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'" size="small">
{{ row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="last_login_at" label="最后登录" width="180" />
<el-table-column prop="created_at" label="创建时间" width="180" />
<el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button
type="danger"
link
size="small"
:disabled="row.id === authStore.user?.id"
@click="handleDelete(row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新建对话框 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="450px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="登录用户名" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" type="password" show-password placeholder="登录密码" />
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="form.nickname" placeholder="显示名称" />
</el-form-item>
<el-form-item label="角色">
<el-select v-model="form.role" style="width: 100%">
<el-option label="管理员" value="admin" />
<el-option label="操作员" value="operator" />
<el-option label="只读" value="viewer" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>