This commit is contained in:
wangjiming
2026-07-27 10:38:16 +08:00
parent b4ff5db17b
commit 4c7d66030c
4 changed files with 279 additions and 20 deletions

View File

@@ -1,12 +1,134 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { getUsers, updateUserAccess } from '@/api/modules/system'
import type { PermissionCode, SystemUser } from '@/types'
const route = useRoute()
const router = useRouter()
const loading = ref(false)
const saving = ref(false)
const userId = route.params.id as string
const target = ref<SystemUser | null>(null)
const checked = ref<PermissionCode[]>([])
const options: PermissionCode[] = [
'dashboard',
'fine-tune',
'model-eval',
'model-inference',
'model-manage',
'dataset',
'data-process',
'data-convert',
'compute',
'hardware',
'logs',
'user-settings',
]
const labels: Record<PermissionCode, string> = {
dashboard: '仪表盘',
'fine-tune': '模型微调',
'model-eval': '模型评估',
'model-inference': '模型推理',
'model-manage': '模型管理',
dataset: '数据集',
'data-process': '数据处理',
'data-convert': '数据转换',
compute: '算力',
hardware: '平台性能',
logs: '日志',
'user-settings': '用户设置',
}
async function load() {
loading.value = true
try {
const users = await getUsers()
const u = users.find((x) => x.id === userId)
if (!u) {
ElMessage.error('用户不存在')
return
}
target.value = u
checked.value = [...u.permissions]
} finally {
loading.value = false
}
}
async function save() {
saving.value = true
try {
await updateUserAccess(userId, { permissions: checked.value })
ElMessage.success('权限已保存')
router.push('/user-settings')
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || '保存失败')
} finally {
saving.value = false
}
}
onMounted(load)
</script>
<template>
<section class="simple-page">
<h1>权限设置</h1>
<p>第一版已支持账号页面权限读取与保存精细化项目/模型/数据集权限将在后续版本补齐</p>
<section class="permission-page" v-loading="loading">
<header class="page-header">
<div>
<h1>权限设置</h1>
<p v-if="target">
为账号 <b>{{ target.username }}</b>{{ target.display_name }}配置可访问的页面权限
</p>
</div>
<el-button @click="$router.push('/user-settings')">返回</el-button>
</header>
<el-form label-width="90px" class="perm-form">
<el-form-item label="账号">{{ target?.username }}</el-form-item>
<el-form-item label="角色">{{ target?.role }}</el-form-item>
<el-form-item label="页面权限">
<el-checkbox-group v-model="checked">
<el-checkbox v-for="opt in options" :key="opt" :value="opt">
{{ labels[opt] }}{{ opt }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button @click="$router.push('/user-settings')">取消</el-button>
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
</el-form-item>
</el-form>
</section>
</template>
<style scoped>
.simple-page {
.permission-page {
padding: 24px;
}
.page-header {
display: flex;
justify-content: space-between;
gap: 16px;
margin-bottom: 18px;
}
.page-header h1 {
margin: 0;
font-size: 24px;
}
.page-header p {
margin: 8px 0 0;
color: #64748b;
}
.perm-form {
max-width: 760px;
}
</style>

View File

@@ -1,8 +1,11 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { getUsers, resetUserPassword } from '@/api/modules/system'
import type { SystemUser } from '@/types'
import { getUsers, resetUserPassword, updateUserAccess, deleteUser } from '@/api/modules/system'
import { useAuthStore } from '@/stores/auth'
import type { SystemUser, UserStatus } from '@/types'
const auth = useAuthStore()
const loading = ref(false)
const users = ref<SystemUser[]>([])
@@ -41,6 +44,27 @@ async function confirmReset() {
}
}
async function toggleStatus(row: SystemUser) {
const next: UserStatus = row.status === 'active' ? 'disabled' : 'active'
try {
await updateUserAccess(row.id, { status: next })
ElMessage.success(next === 'active' ? '已启用' : '已禁用')
await loadUsers()
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || '操作失败')
}
}
async function removeUser(row: SystemUser) {
try {
await deleteUser(row.id, auth.username)
ElMessage.success('用户已删除')
await loadUsers()
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || '删除失败')
}
}
onMounted(loadUsers)
</script>
@@ -58,14 +82,39 @@ onMounted(loadUsers)
<el-table-column prop="username" label="账号" min-width="140" />
<el-table-column prop="display_name" label="显示名称" min-width="160" />
<el-table-column prop="role" label="角色" width="120" />
<el-table-column prop="status" label="状态" width="120" />
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'active' ? 'success' : 'info'">
{{ row.status === 'active' ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="权限数" width="120">
<template #default="{ row }">{{ row.permissions?.length || 0 }}</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" min-width="180" />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="300" fixed="right">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openReset(row)">重置密码</el-button>
<el-button link type="primary" size="small" @click="$router.push(`/user-settings/${row.id}/permission`)">权限</el-button>
<el-button
v-if="!row.protected"
link
:type="row.status === 'active' ? 'danger' : 'success'"
size="small"
@click="toggleStatus(row)"
>{{ row.status === 'active' ? '禁用' : '启用' }}</el-button>
<el-popconfirm
v-if="!row.protected && row.username !== auth.username"
title="确定删除该账号?此操作不可恢复"
confirm-button-text="删除"
cancel-button-text="取消"
@confirm="removeUser(row)"
>
<template #reference>
<el-button link type="danger" size="small">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>