审计日志修改完善

This commit is contained in:
dxc
2026-04-20 11:39:28 +08:00
parent 7d683f3e65
commit becd3cb010
2 changed files with 119 additions and 4 deletions

View File

@ -62,6 +62,28 @@
<el-tag type="warning" effect="plain" round>当前配置: {{ getRoleLabel(currentRole) }}</el-tag>
</div>
<!-- 新增拉取其他角色权限的操作区 -->
<div class="pull-permission-bar">
<span class="pull-label">从其他角色复制权限</span>
<el-select
v-model="sourceRoleForClone"
placeholder="选择源角色..."
clearable
size="default"
@change="handleClonePermissions"
class="clone-select"
>
<el-option
v-for="role in availableSourceRoles"
:key="role.value"
:label="role.label"
:value="role.value"
:disabled="role.value === currentRole"
/>
</el-select>
<span class="pull-hint" v-if="!sourceRoleForClone">选择后将覆盖当前未保存的勾选状态</span>
</div>
<el-table
:data="tableData"
row-key="id"
@ -78,20 +100,25 @@
<el-table-column label="访问权限" width="150" align="center">
<template #default="{ row }">
<!-- 父级目录隐藏复选框仅叶子节点可操作 -->
<el-checkbox
v-if="row.type !== 'menu' || !row.children?.length"
v-model="row.hasRead"
@change="(val) => handleReadChange(val, row)"
class="custom-checkbox"
>
<span :class="{ 'text-active': row.hasRead }">可见 (Read)</span>
</el-checkbox>
<span v-else class="text-gray">-</span>
</template>
</el-table-column>
<el-table-column label="操作权限" width="180" align="center">
<template #default="{ row }">
<div v-if="row.operationCode">
<!-- 父级目录隐藏操作权限列 -->
<div v-if="row.type !== 'menu' || !row.children?.length">
<el-checkbox
v-if="row.operationCode"
v-model="row.hasWrite"
:disabled="!row.hasRead"
@change="(val) => handleWriteChange(val, row)"
@ -99,6 +126,7 @@
>
<span :class="{ 'text-active': row.hasWrite, 'text-disabled': !row.hasRead }">可编辑 (Write)</span>
</el-checkbox>
<span v-else class="text-gray">-</span>
</div>
<span v-else class="text-gray">-</span>
</template>
@ -153,8 +181,8 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { User, UserFilled, ArrowRight, Setting, Check, Avatar } from '@element-plus/icons-vue'
import { getAllPermissionTree, getRolePermissions, saveRolePermissions } from '@/api/system/permission'
@ -180,6 +208,7 @@ interface PermissionNode {
const loading = ref(false)
const saving = ref(false)
const currentRole = ref('')
const sourceRoleForClone = ref('') // 用于克隆权限的源角色
const roleList = [
{ label: '超级管理员', value: 'SUPER_ADMIN' },
{ label: '主管', value: 'SUPERVISOR' },
@ -269,6 +298,8 @@ const transformData = (nodes: any[]): PermissionNode[] => {
// 2. 切换角色:回显权限
const handleRoleSelect = async (roleCode: string) => {
currentRole.value = roleCode
// 切换角色时清空克隆选择
sourceRoleForClone.value = ''
loading.value = true
try {
@ -286,6 +317,53 @@ const handleRoleSelect = async (roleCode: string) => {
}
}
// 可用的源角色列表(排除当前已选角色)
const availableSourceRoles = computed(() => {
return roleList.filter(r => r.value !== currentRole.value)
})
// ★ 新增:从其他角色拉取权限
const handleClonePermissions = async (sourceRole: string) => {
if (!sourceRole) {
sourceRoleForClone.value = ''
return
}
// 确认提示
try {
await ElMessageBox.confirm(
`将从角色【${getRoleLabel(sourceRole)}】复制权限到【${getRoleLabel(currentRole.value)}】,覆盖当前未保存的勾选状态,是否继续?`,
'权限拉取确认',
{
confirmButtonText: '确认拉取',
cancelButtonText: '取消',
type: 'warning'
}
)
} catch {
// 用户取消
sourceRoleForClone.value = ''
return
}
loading.value = true
try {
// 调用后端 API 获取源角色的权限
const res: any = await getRolePermissions(sourceRole)
if (res.code === 200) {
const perms = new Set([...(res.data.menus || []), ...(res.data.elements || [])])
// 递归设置表格每一行的状态
setRowStatus(tableData.value, perms)
ElMessage.success(`已从【${getRoleLabel(sourceRole)}】拉取权限,请修改后点击保存`)
}
} catch (e) {
ElMessage.error('拉取权限失败')
} finally {
sourceRoleForClone.value = '' // 清空选择器
loading.value = false
}
}
// 递归回显状态
const setRowStatus = (rows: PermissionNode[], perms: Set<any>) => {
rows.forEach(row => {
@ -599,6 +677,33 @@ onMounted(() => {
overflow: auto;
}
/* 新增:拉取权限操作条 */
.pull-permission-bar {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 15px;
margin-bottom: 15px;
background: #f0f7ff;
border-radius: 6px;
border: 1px solid #d9ecff;
}
.pull-label {
font-size: 14px;
color: #303133;
white-space: nowrap;
}
.clone-select {
width: 180px;
}
.pull-hint {
font-size: 12px;
color: #909399;
}
/* 表格内样式 */
.custom-checkbox {
height: auto;