更新平台治理
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
changeMyPassword,
|
||||
@@ -8,30 +8,12 @@ import {
|
||||
resetUserPassword,
|
||||
updateUserAccess,
|
||||
} from '@/api/modules/system'
|
||||
import type { PermissionCode, SystemUser, UserStatus } from '@/types'
|
||||
import type { SystemUser, UserStatus } from '@/types'
|
||||
import { statusLabel, statusTagType } from '@/utils/status'
|
||||
|
||||
const loading = ref(false)
|
||||
const users = ref<SystemUser[]>([])
|
||||
|
||||
// 权限码 -> 中文名(与路由模块一一对应)
|
||||
const PERMISSION_LABELS: Record<PermissionCode, string> = {
|
||||
dashboard: '服务看板',
|
||||
'fine-tune': '模型训练',
|
||||
'model-eval': '模型评测',
|
||||
'model-inference': '模型推理',
|
||||
'model-manage': '模型管理',
|
||||
dataset: '数据集管理',
|
||||
'data-process': '数据处理',
|
||||
'data-convert': '数据转换',
|
||||
compute: '计算资源',
|
||||
hardware: '硬件监控',
|
||||
logs: '日志中心',
|
||||
'user-settings': '用户与权限',
|
||||
}
|
||||
|
||||
const ALL_PERMISSIONS = Object.keys(PERMISSION_LABELS) as PermissionCode[]
|
||||
|
||||
async function loadUsers() {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -59,14 +41,6 @@ function asSystemUser(row: unknown): SystemUser {
|
||||
return row as SystemUser
|
||||
}
|
||||
|
||||
function userPermissions(row: unknown): PermissionCode[] {
|
||||
return (asSystemUser(row).permissions || []) as PermissionCode[]
|
||||
}
|
||||
|
||||
function permissionLabel(code: PermissionCode): string {
|
||||
return PERMISSION_LABELS[code] || code
|
||||
}
|
||||
|
||||
// ---------- 启停 ----------
|
||||
async function toggleStatus(row: SystemUser, next: boolean) {
|
||||
const nextStatus: UserStatus = next ? 'active' : 'disabled'
|
||||
@@ -135,60 +109,6 @@ async function confirmChangeMyPwd() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- 页面权限 ----------
|
||||
const permDialog = reactive({
|
||||
visible: false,
|
||||
id: '',
|
||||
name: '',
|
||||
checked: [] as PermissionCode[],
|
||||
saving: false,
|
||||
})
|
||||
function openPerms(row: SystemUser) {
|
||||
permDialog.id = row.id
|
||||
permDialog.name = row.display_name
|
||||
// admin 用户强制全选且只读
|
||||
if (row.role === 'admin' || row.protected) {
|
||||
permDialog.checked = [...ALL_PERMISSIONS]
|
||||
} else {
|
||||
// 非 admin 用户去掉 user-settings
|
||||
permDialog.checked = (row.permissions || []).filter((p) => p !== 'user-settings')
|
||||
}
|
||||
permDialog.visible = true
|
||||
}
|
||||
async function confirmPerms() {
|
||||
if (permReadonly.value) {
|
||||
permDialog.visible = false
|
||||
return
|
||||
}
|
||||
// 双重保险:非 admin 用户不允许勾选 user-settings
|
||||
if (!isTargetAdmin.value) {
|
||||
permDialog.checked = permDialog.checked.filter((p) => p !== 'user-settings')
|
||||
}
|
||||
permDialog.saving = true
|
||||
try {
|
||||
await updateUserAccess(permDialog.id, { permissions: permDialog.checked })
|
||||
ElMessage.success(`已更新 ${permDialog.name} 的页面权限`)
|
||||
permDialog.visible = false
|
||||
await loadUsers()
|
||||
} catch {
|
||||
ElMessage.error('权限更新失败')
|
||||
} finally {
|
||||
permDialog.saving = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 权限列:admin 用户全选且只读,非 admin 用户不显示 user-settings */
|
||||
const isTargetAdmin = computed(() => {
|
||||
const u = users.value.find((u) => u.id === permDialog.id)
|
||||
return u?.role === 'admin' || u?.protected === true
|
||||
})
|
||||
const permColumns = computed(() => {
|
||||
if (isTargetAdmin.value) return ALL_PERMISSIONS
|
||||
// 非 admin 用户不能拥有 user-settings 权限
|
||||
return ALL_PERMISSIONS.filter((c) => c !== 'user-settings')
|
||||
})
|
||||
const permReadonly = computed(() => isTargetAdmin.value)
|
||||
|
||||
// ---------- 删除 ----------
|
||||
async function removeUser(row: SystemUser) {
|
||||
try {
|
||||
@@ -216,7 +136,7 @@ async function removeUser(row: SystemUser) {
|
||||
<header class="page-header">
|
||||
<div>
|
||||
<h1>用户设置</h1>
|
||||
<p>管理平台账号、角色状态、登录密码与页面权限。</p>
|
||||
<p>管理平台账号、角色状态与登录密码。</p>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="openChangeMyPwd">修改密码</el-button>
|
||||
@@ -233,21 +153,6 @@ async function removeUser(row: SystemUser) {
|
||||
<el-tag :type="statusTagType(asSystemUser(row).status)" size="small">{{ statusLabel(asSystemUser(row).status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="页面权限" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
v-for="p in userPermissions(row).slice(0, 3)"
|
||||
:key="p"
|
||||
size="small"
|
||||
type="info"
|
||||
class="perm-tag"
|
||||
>{{ permissionLabel(p) }}</el-tag>
|
||||
<span v-if="userPermissions(row).length > 3" class="perm-more">
|
||||
+{{ userPermissions(row).length - 3 }}
|
||||
</span>
|
||||
<span v-if="!userPermissions(row).length" class="perm-more">无</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" label="创建时间" min-width="180" />
|
||||
<el-table-column label="操作" width="260" fixed="right">
|
||||
<template #default="{ row }">
|
||||
@@ -265,11 +170,6 @@ async function removeUser(row: SystemUser) {
|
||||
:disabled="asSystemUser(row).protected"
|
||||
@click="openResetPwd(asSystemUser(row))"
|
||||
>重置密码</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openPerms(asSystemUser(row))"
|
||||
>页面权限</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@@ -290,26 +190,6 @@ async function removeUser(row: SystemUser) {
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 页面权限 -->
|
||||
<el-dialog v-model="permDialog.visible" title="页面权限" width="540px">
|
||||
<p class="dlg-tip">
|
||||
为 <b>{{ permDialog.name }}</b> 分配可访问的页面模块:
|
||||
<el-tag v-if="permReadonly" type="warning" size="small" style="margin-left: 8px">管理员权限不可更改</el-tag>
|
||||
</p>
|
||||
<el-checkbox-group v-model="permDialog.checked" class="perm-group" :disabled="permReadonly">
|
||||
<el-checkbox
|
||||
v-for="code in permColumns"
|
||||
:key="code"
|
||||
:value="code"
|
||||
:label="PERMISSION_LABELS[code]"
|
||||
/>
|
||||
</el-checkbox-group>
|
||||
<template #footer>
|
||||
<el-button @click="permDialog.visible = false">{{ permReadonly ? '关闭' : '取消' }}</el-button>
|
||||
<el-button v-if="!permReadonly" type="primary" :loading="permDialog.saving" @click="confirmPerms">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 修改自己的密码 -->
|
||||
<el-dialog v-model="myPwdDialog.visible" title="修改密码" width="420px">
|
||||
<el-form label-width="80px">
|
||||
@@ -350,24 +230,8 @@ async function removeUser(row: SystemUser) {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.perm-tag {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.perm-more {
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.dlg-tip {
|
||||
margin: 0 0 12px;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.perm-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user