6 changed files with 2000 additions and 19 deletions
-
28src/router/index.js
-
17src/utils/menuTreePermission.js
-
89src/views/permissions/permissions.vue
-
833src/views/permissions/rolePermission.vue
-
1032src/views/permissions/userPermission.vue
-
12src/views/usergold/gold/clientCount.vue
@ -0,0 +1,89 @@ |
|||
<template> |
|||
<div> |
|||
<!-- 这里放置标签切换的按钮 --> |
|||
<el-button-group> |
|||
<!-- 切换后状态显示 primary 样式否则是默认样式 --> |
|||
<el-button |
|||
:type="activeTab === 'userPermission' ? 'primary' : 'default'" |
|||
@click="navigateTo('userPermission')" |
|||
:disabled="!hasDetail" |
|||
> |
|||
用户管理 |
|||
</el-button> |
|||
<el-button |
|||
:type="activeTab === 'rolePermission' ? 'primary' : 'default'" |
|||
@click="navigateTo('rolePermission')" |
|||
:disabled="!hasBalance" |
|||
> |
|||
角色管理 |
|||
</el-button> |
|||
</el-button-group> |
|||
<!-- 渲染子路由组件 --> |
|||
<router-view></router-view> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import {onMounted, ref, watch} from 'vue'; |
|||
import {useRoute, useRouter} from 'vue-router'; |
|||
import {storeToRefs} from "pinia"; |
|||
import {useAdminStore} from "@/store/index.js"; |
|||
import {hasMenuPermission, permissionMapping} from "@/utils/menuTreePermission.js"; |
|||
|
|||
const router = useRouter(); |
|||
const route = useRoute(); |
|||
const adminStore = useAdminStore(); |
|||
const {menuTree} = storeToRefs(adminStore); |
|||
|
|||
const activeTab = ref(''); |
|||
const hasDetail = ref(false); |
|||
const hasBalance = ref(false); |
|||
// 导航方法 |
|||
const navigateTo = (name) => { |
|||
activeTab.value = name; |
|||
router.push({name}); |
|||
}; |
|||
|
|||
|
|||
// 初始化权限状态 |
|||
const initPermissions = () => { |
|||
if (!menuTree.value || !menuTree.value.length) return; |
|||
|
|||
hasDetail.value = hasMenuPermission(menuTree.value, permissionMapping.View_Permission); |
|||
hasBalance.value = hasMenuPermission(menuTree.value, permissionMapping.View_Role); |
|||
}; |
|||
|
|||
// 默认跳转逻辑 |
|||
const getDefaultAuditRoute = () => { |
|||
initPermissions(); |
|||
if (hasDetail.value) return 'userPermission'; |
|||
if (hasBalance.value) return 'rolePermission'; |
|||
return 'userPermission'; |
|||
}; |
|||
|
|||
// 监听路由变化更新标签状态 |
|||
watch(() => route.name, (newName) => { |
|||
initPermissions() |
|||
if (newName === 'userPermission' || newName === 'rolePermission') { |
|||
activeTab.value = newName; |
|||
} else if (newName === 'permissions') { |
|||
// 每次访问 /permissions 都进行默认跳转 |
|||
const defaultRoute = getDefaultAuditRoute(); |
|||
navigateTo(defaultRoute); |
|||
} |
|||
}); |
|||
|
|||
// 初始化逻辑 |
|||
onMounted(() => { |
|||
initPermissions() |
|||
if (route.name === 'permissions') { |
|||
const defaultRoute = getDefaultAuditRoute(); |
|||
navigateTo(defaultRoute); |
|||
} else { |
|||
// 非父路由初始化当前标签状态 |
|||
if (route.name === 'userPermission' || route.name === 'rolePermission') { |
|||
activeTab.value = route.name; |
|||
} |
|||
} |
|||
}); |
|||
</script> |
@ -0,0 +1,833 @@ |
|||
<script setup> |
|||
import {nextTick, onMounted, reactive, ref} from 'vue' |
|||
import {ElMessage} from 'element-plus' |
|||
import _ from 'lodash' |
|||
import request from '@/util/http' |
|||
import API from '@/util/http' |
|||
// 客户明细表格 什么表格??????? |
|||
const tableData = ref([]) |
|||
const roleData = ref([]) |
|||
const total = ref(100) |
|||
const roleTotal = ref(100)//角色分页 |
|||
// 搜索admin |
|||
const admin = ref({ |
|||
account: '', |
|||
market: '', |
|||
postiton: '' |
|||
}) |
|||
// 角色搜索 |
|||
const role = ref({ |
|||
name: '' |
|||
}) |
|||
// 搜索对象 |
|||
const getObj = ref({ |
|||
pageNum: 1, |
|||
pageSize: 10 |
|||
}) |
|||
// 角色搜索对象 |
|||
const getRoleObj = ref({ |
|||
pageNum: 1, |
|||
pageSize: 10 |
|||
}) |
|||
//选地区 |
|||
const market = ref([]) |
|||
// 选部门 |
|||
const postiton = ref([]) |
|||
|
|||
// 新增角色弹窗 |
|||
const permissionAddVisible = ref(false) |
|||
// 新增角色对象 |
|||
const addRole = ref({ |
|||
roleName: '', |
|||
parentId: null, |
|||
checkedKeys: [], |
|||
grade: '', |
|||
market: '' |
|||
}) |
|||
const addRoleMarket = ref([]) |
|||
|
|||
//这是获取用户信息的接口 |
|||
const adminData = ref({}) |
|||
const getAdminData = async function () { |
|||
try { |
|||
const result = await API({url: '/admin/userinfo', data: {}}) |
|||
adminData.value = result |
|||
console.log('管理员用户信息', adminData.value) |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
const viewRole = ref([]) |
|||
const getRolePermission = async function () { |
|||
const result = await request({ |
|||
url: '/menu/tree', |
|||
data: { |
|||
"id": adminData.value.roleId |
|||
} |
|||
}) |
|||
viewRole.value = collectIds(result.data) |
|||
console.log('result111', viewRole.value); |
|||
} |
|||
|
|||
const get = async function (val) { |
|||
try { |
|||
if (typeof val === 'number') { |
|||
getObj.value.pageNum = val |
|||
} |
|||
console.log('搜索参数', getObj.value, admin.value) |
|||
const result = await request({ |
|||
url: '/permission/getPermission', |
|||
data: { |
|||
...getObj.value, |
|||
permission: { |
|||
...admin.value |
|||
} |
|||
} |
|||
}) |
|||
tableData.value = result.data.list |
|||
console.log('tableData', tableData.value) |
|||
total.value = result.data.total |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
const getRoleList = async function (val) { |
|||
try { |
|||
if (typeof val === 'number') { |
|||
getObj.value.pageNum = val |
|||
} |
|||
console.log('搜索参数', getObj.value, role.value) |
|||
const result = await request({ |
|||
url: '/role/selectBy', |
|||
data: { |
|||
...getRoleObj.value, |
|||
roleVo: { |
|||
roleName: role.value.name |
|||
} |
|||
} |
|||
}) |
|||
roleData.value = result.data.list |
|||
console.log('roleData', roleData.value) |
|||
roleTotal.value = result.data.total |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
// 试试D老师的方法 |
|||
const formatPermissions = (tree) => { |
|||
if (!tree || tree.length === 0) return ''; |
|||
|
|||
return tree.map(menu => { |
|||
const mainMenu = menu.menuName; |
|||
const subMenus = menu.children?.map(child => child.menuName) || []; |
|||
|
|||
// 如果有子菜单,显示前2个子菜单名称 |
|||
if (subMenus.length > 0) { |
|||
const maxSub = Math.min(2, subMenus.length); |
|||
const subText = subMenus.slice(0, maxSub).join('、'); |
|||
const moreText = subMenus.length > maxSub ? '...' : ''; |
|||
return `${mainMenu}+${subText}${moreText}`; |
|||
} |
|||
|
|||
// 没有子菜单时只显示主菜单 |
|||
return mainMenu; |
|||
}).join('+'); |
|||
}; |
|||
const trimJwCode = () => { |
|||
if (admin.value.account) { |
|||
admin.value.account = admin.value.account.replace(/\s/g, ''); |
|||
} |
|||
} |
|||
|
|||
const searchRole = function () { |
|||
trimJwCode(); |
|||
getObj.value.pageNum = 1 |
|||
getRoleList() |
|||
} |
|||
// 重置 |
|||
const reset = function () { |
|||
admin.value = {} |
|||
role.value.name = '' |
|||
|
|||
get() |
|||
getRoleList() |
|||
} |
|||
const RoleArea = ref([]) |
|||
const getRoleArea = async function () { |
|||
try { |
|||
const result = await request({ |
|||
url: '/general/allRoleMarket', |
|||
data: {} |
|||
}) |
|||
RoleArea.value = result.data |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
const getArea = async function () { |
|||
try { |
|||
const result = await request({ |
|||
url: '/general/adminMarkets', |
|||
data: {account: adminData.value.account} |
|||
}) |
|||
market.value = result.data |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
// 获取部门 |
|||
const getStore = async function () { |
|||
try { |
|||
const result = await request({ |
|||
url: '/permission/getposition', |
|||
data: {} |
|||
}) |
|||
postiton.value = result.data |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
// 新增角色弹窗 |
|||
const openPermissionAddVisible = function () { |
|||
permissionAddVisible.value = true |
|||
getRoles() |
|||
getLists() |
|||
} |
|||
|
|||
const closePermissionAddVisible = function () { |
|||
addRole.value = { |
|||
roleName: '', |
|||
parentId: null, |
|||
checkedKeys: [], |
|||
grade: '', |
|||
market: '' |
|||
} |
|||
permissionAddVisible.value = false |
|||
Ref.value.resetFields(); |
|||
getRoleList() |
|||
} |
|||
|
|||
// 新增角色初始化 |
|||
const permissionAddInit = function () { |
|||
openPermissionAddVisible() |
|||
} |
|||
|
|||
// 表单验证ref |
|||
const Ref = ref(null) |
|||
|
|||
// 权限类别 |
|||
const permissionList = ref([]) |
|||
const getRoles = async function () { |
|||
try { |
|||
const res = await API({url: '/role/selectAll'}) |
|||
permissionList.value = res.data.map(item => ({ |
|||
label: item.roleName, |
|||
value: item.id |
|||
})) |
|||
|
|||
console.log('权限列表:', permissionList.value) |
|||
} catch (error) { |
|||
console.error('获取权限列表失败:', error) |
|||
} |
|||
} |
|||
|
|||
const collectIds = (tree) => { |
|||
let ids = []; |
|||
tree.forEach((node) => { |
|||
ids.push(node.id); |
|||
if (node.children && node.children.length > 0) { |
|||
ids = ids.concat(collectIds(node.children)); |
|||
} |
|||
}); |
|||
return ids; |
|||
}; |
|||
|
|||
//给data数据加上disabled属性,控制是否禁用 |
|||
function processTreeData(data) { |
|||
return data.map(item => ({ |
|||
...item, |
|||
disabled: item.id != null || item.menuName.includes("敏感权限"), //控制权限显示的条件 |
|||
children: item.children ? processTreeData(item.children) : [] |
|||
})); |
|||
} |
|||
|
|||
const handleAddRole = async function () { |
|||
try { |
|||
await new Promise((resolve, reject) => { |
|||
Ref.value.validate((valid) => { |
|||
if (valid) { |
|||
resolve(); // 验证通过,继续执行后续代码 |
|||
} else { |
|||
reject(new Error('请检查并完善表单信息')); // 验证失败,抛出错误 |
|||
} |
|||
}); |
|||
}); |
|||
addRole.value.roleName = addRole.value.roleName.replace(/\s+/g, ''); |
|||
console.log('去除角色名空格:', addRole.value.roleName); |
|||
|
|||
// 确保提交时包含所有选中的权限ID(包括父节点) |
|||
const finalCheckedKeys = addRole.value.checkedKeys || []; |
|||
|
|||
const res = await API({ |
|||
url: '/role/add', |
|||
data: { |
|||
"roleName": addRole.value.roleName, |
|||
"menuIds": finalCheckedKeys, |
|||
"priority": addRole.value.grade, |
|||
"fatherId": addRole.value.parentId, |
|||
"market": addRole.value.market |
|||
} |
|||
}) |
|||
if (res.code === 200) { |
|||
ElMessage.success('角色' + addRole.value.roleName + '添加成功') |
|||
console.log('成功了,看看addRole', addRole.value) |
|||
console.log('提交的权限ID列表:', finalCheckedKeys); |
|||
closePermissionAddVisible() |
|||
} else { |
|||
ElMessage.error(res.msg) |
|||
} |
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
console.log('失败,看看addRole', addRole.value); |
|||
} |
|||
} |
|||
|
|||
const handleRolePageSizeChange = (val) => { |
|||
getRoleObj.value.pageSize = val |
|||
getRoleList() // 调用角色管理的查询 |
|||
} |
|||
|
|||
// 角色管理分页 - 当前页变化 |
|||
const handleRoleCurrentChange = (val) => { |
|||
getRoleObj.value.pageNum = val |
|||
getRoleList() // 调用角色管理的查询 |
|||
} |
|||
|
|||
const data = ref([]) |
|||
const getLists = async function () { |
|||
try { |
|||
console.log('addRole.value.roleId', addRole.value.roleId); |
|||
|
|||
let roleId = addRole.value.parentId |
|||
if (addRole.value.parentId === null || addRole.value.parentId === undefined) { |
|||
roleId = 2 |
|||
} |
|||
const res = await API({ |
|||
url: '/menu/tree', |
|||
data: {id: roleId} |
|||
}) |
|||
data.value = res.data |
|||
data.value = data.value.filter(item => item.id !== 9); |
|||
console.log('看看data', data.value) |
|||
console.log('parentID:', addRole.value.parentId, 'roleId:', roleId) |
|||
|
|||
if (addRole.value.parentId && addRole.value.parentId !== 2) { |
|||
const result = await API({ |
|||
url: '/general/roleMarket', |
|||
data: {id: addRole.value.parentId} |
|||
}) |
|||
if (result.code === 200) { |
|||
if (typeof result.data === 'string' && result.data) { |
|||
addRoleMarket.value = result.data.split(','); |
|||
addRole.value.market = '' |
|||
} else if (Array.isArray(result.data)) { |
|||
addRoleMarket.value = result.data |
|||
addRole.value.market = '' |
|||
} else { |
|||
addRoleMarket.value = []; |
|||
addRole.value.market = '' |
|||
} |
|||
} else { |
|||
ElMessage.error('该上级角色无所属地区') |
|||
console.log('该上级角色无所属地区'); |
|||
|
|||
} |
|||
console.log('addRoleMarket.value', addRoleMarket.value); |
|||
} else { |
|||
addRoleMarket.value = RoleArea.value |
|||
console.log('elseRoleArea', RoleArea); |
|||
|
|||
} |
|||
|
|||
} catch (error) { |
|||
console.log('请求失败', error) |
|||
} |
|||
} |
|||
const treeRef = ref(null) |
|||
// 处理编辑角色权限时的勾选事件 |
|||
const handleEditRolePermissionCheck = (checkedNodes, checkedInfo) => { |
|||
const {checkedKeys, checkedNodes: allCheckedNodes} = checkedInfo; |
|||
|
|||
// 判断是否有选中的节点 |
|||
if (allCheckedNodes.length === 0) { |
|||
permissionEditRoleObj.value.checkedKeys = []; |
|||
return; |
|||
} |
|||
|
|||
// 由于设置了 check-strictly="false",Element Plus 会自动处理父子节点联动 |
|||
// 我们只需要使用 checkedKeys,它已经包含了所有必要的节点ID |
|||
permissionEditRoleObj.value.checkedKeys = checkedKeys; |
|||
|
|||
console.log('编辑角色选中的权限ID:', checkedKeys); |
|||
console.log('选中的节点数量:', allCheckedNodes.length); |
|||
}; |
|||
const handleCheckChange = async (checkedNodes, checkedInfo) => { |
|||
const {checkedKeys, checkedNodes: allCheckedNodes} = checkedInfo; |
|||
|
|||
// 判断是否有选中的节点 |
|||
if (allCheckedNodes.length === 0) { |
|||
addRole.value.checkedKeys = []; |
|||
return; |
|||
} |
|||
|
|||
// 创建一个Set存储所有需要选中的ID(包括父级) |
|||
const allKeys = new Set(checkedKeys); |
|||
|
|||
// 遍历所有选中的节点,为每个节点添加其父级 |
|||
allCheckedNodes.forEach(node => { |
|||
// 为每个选中的节点单独查找父级 |
|||
selectParentNodes(data.value, node.id, allKeys); |
|||
}); |
|||
|
|||
// 将Set转换为数组并更新 |
|||
addRole.value.checkedKeys = Array.from(allKeys); |
|||
console.log('新增角色包含所有父级的选中项:', addRole.value.checkedKeys); |
|||
}; |
|||
|
|||
const selectParentNodes = (treeData, nodeId, checkedKeys) => { |
|||
if (!Array.isArray(treeData)) return false; |
|||
|
|||
for (const item of treeData) { |
|||
// 先检查子节点 |
|||
if (item.children && item.children.length > 0) { |
|||
const foundInChildren = selectParentNodes(item.children, nodeId, checkedKeys); |
|||
if (foundInChildren) { |
|||
// 找到子节点后添加当前节点(父节点) |
|||
checkedKeys.add(item.id); |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
// 检查当前节点是否为目标节点 |
|||
if (item.id === nodeId) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
}; |
|||
//点击角色权限菜单树点击展示逻辑 |
|||
const menuTreeVisible = ref(false); |
|||
const currentRoleMenuTree = ref([]); |
|||
const currentRoleName = ref(''); |
|||
const Rolecheckedkeys = ref([]) |
|||
const showMenuTree = (treeData, roleName) => { |
|||
currentRoleMenuTree.value = processTreeData(treeData) || []; |
|||
console.log('currentRoleMenuTree.value', currentRoleMenuTree.value); |
|||
Rolecheckedkeys.value = collectIds(treeData) |
|||
console.log('Rolecheckedkeys', Rolecheckedkeys.value); |
|||
|
|||
currentRoleName.value = roleName || '权限详情'; |
|||
menuTreeVisible.value = true; |
|||
}; |
|||
|
|||
// 编辑角色对象 |
|||
const permissionEditRoleObj = ref({ |
|||
id: null, |
|||
roleName: '', |
|||
market: '', |
|||
parentId: null, |
|||
parentName: '', |
|||
checkedKeys: [], |
|||
grade: '', |
|||
}); |
|||
|
|||
// 编辑角色弹窗 |
|||
const permissionEditRoleVisible = ref(false); |
|||
|
|||
const collectIds2 = (tree) => { |
|||
let ids = []; |
|||
tree.forEach((node) => { |
|||
// 如果当前节点没有 children 或 children 为空,说明是叶子节点 |
|||
if (!node.children || node.children.length === 0) { |
|||
ids.push(node.id); |
|||
} else { |
|||
// 如果有 children,递归收集子节点的叶子节点 |
|||
ids = ids.concat(collectIds2(node.children)); |
|||
} |
|||
}); |
|||
return ids; |
|||
}; |
|||
|
|||
|
|||
// 编辑角色初始化 |
|||
const permissionEditRoleInit = async function (row) { |
|||
console.log('row', row); |
|||
console.log('row.tree', row.tree); |
|||
permissionEditRoleObj.value = {}; |
|||
permissionEditRoleObj.value.id = row.id; |
|||
permissionEditRoleObj.value.roleName = row.roleName; |
|||
permissionEditRoleObj.value.market = row.market; |
|||
permissionEditRoleObj.value.parentId = row.fatherId; |
|||
permissionEditRoleObj.value.parentName = row.fatherName; |
|||
permissionEditRoleObj.value.grade = row.priority; |
|||
|
|||
try { |
|||
let roleId = permissionEditRoleObj.value.parentId; |
|||
// 如果没有上级角色,设置为管理员的id |
|||
if (permissionEditRoleObj.value.parentId === null || permissionEditRoleObj.value.parentId === undefined) { |
|||
roleId = 2; |
|||
} |
|||
// 调用 /tree 接口,使用上级角色 ID 获取权限列表 |
|||
const res = await API({ |
|||
url: '/menu/tree', |
|||
data: {id: roleId} |
|||
}); |
|||
data.value = res.data; |
|||
data.value = data.value.filter(item => item.id !== 9); |
|||
|
|||
// 收集当前行权限树的叶子节点id(只收集实际选中的叶子节点) |
|||
if (row.tree && row.tree.length > 0) { |
|||
const leafIds = collectIds2(row.tree); |
|||
permissionEditRoleObj.value.checkedKeys = leafIds; |
|||
console.log('编辑角色初始化时的权限列表', permissionEditRoleObj.value.checkedKeys); |
|||
} else { |
|||
permissionEditRoleObj.value.checkedKeys = []; |
|||
} |
|||
} catch (error) { |
|||
console.log('根据上级角色获取权限列表失败', error); |
|||
data.value = []; |
|||
permissionEditRoleObj.value.checkedKeys = []; |
|||
} |
|||
console.log('编辑角色', permissionEditRoleObj.value); |
|||
permissionEditRoleVisible.value = true; |
|||
|
|||
// 等待DOM更新后手动设置树的选中状态 |
|||
await nextTick(); |
|||
if (treeRef.value && permissionEditRoleObj.value.checkedKeys.length > 0) { |
|||
treeRef.value.setCheckedKeys(permissionEditRoleObj.value.checkedKeys); |
|||
console.log('手动设置树的选中状态:', permissionEditRoleObj.value.checkedKeys); |
|||
} |
|||
}; |
|||
|
|||
// 编辑角色提交 |
|||
const permissionEditRole = async function () { |
|||
try { |
|||
await new Promise((resolve, reject) => { |
|||
Ref.value.validate((valid) => { |
|||
if (valid) { |
|||
resolve(); |
|||
} else { |
|||
reject(new Error('请检查并完善表单信息')); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
// 确保提交时包含所有选中的权限ID(包括父节点) |
|||
let finalCheckedKeys = permissionEditRoleObj.value.checkedKeys || []; |
|||
|
|||
// 为所有选中的节点添加其父节点ID |
|||
const allKeys = new Set(finalCheckedKeys); |
|||
finalCheckedKeys.forEach(nodeId => { |
|||
selectParentNodesForSubmit(data.value, nodeId, allKeys); |
|||
}); |
|||
|
|||
finalCheckedKeys = Array.from(allKeys); |
|||
|
|||
const res = await API({ |
|||
url: '/menu/update', |
|||
data: { |
|||
"id": permissionEditRoleObj.value.id, |
|||
"roleName": permissionEditRoleObj.value.roleName, |
|||
"menuIds": finalCheckedKeys, |
|||
"priority": permissionEditRoleObj.value.grade, |
|||
"fatherId": permissionEditRoleObj.value.parentId, |
|||
"market": permissionEditRoleObj.value.market |
|||
} |
|||
}); |
|||
if (res.code === 200) { |
|||
console.log('编辑角色成功', permissionEditRoleObj.value); |
|||
console.log('提交的权限ID列表:', finalCheckedKeys); |
|||
permissionEditRoleVisible.value = false; |
|||
getRoleList(); |
|||
ElMessage.success('编辑角色成功'); |
|||
} else if (res.code === 0) { |
|||
console.log('角色名重复', permissionEditRoleObj.value); |
|||
ElMessage.error('角色名重复'); |
|||
} else { |
|||
console.log('编辑角色失败', res); |
|||
ElMessage.error('编辑角色失败'); |
|||
} |
|||
} catch (error) { |
|||
console.log('编辑角色失败', error); |
|||
console.log('失败,看看permissionEditRoleObj', permissionEditRoleObj.value); |
|||
} |
|||
}; |
|||
|
|||
// 为提交时查找父节点的辅助函数 |
|||
const selectParentNodesForSubmit = (treeData, nodeId, checkedKeys) => { |
|||
if (!Array.isArray(treeData)) return false; |
|||
|
|||
for (const item of treeData) { |
|||
// 先检查子节点 |
|||
if (item.children && item.children.length > 0) { |
|||
const foundInChildren = selectParentNodesForSubmit(item.children, nodeId, checkedKeys); |
|||
if (foundInChildren) { |
|||
// 找到子节点后添加当前节点(父节点) |
|||
checkedKeys.add(item.id); |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
// 检查当前节点是否为目标节点 |
|||
if (item.id === nodeId) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
}; |
|||
|
|||
const Rolerules = reactive({ |
|||
roleName: [ |
|||
{required: true, message: '请输入角色名称', trigger: 'blur'}, |
|||
{min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur'} |
|||
], |
|||
market: [ |
|||
{required: true, message: '请选择所属地区', trigger: 'change'} |
|||
], |
|||
grade: [ |
|||
{required: true, message: '请输入优先级', trigger: 'blur'}, |
|||
{pattern: /^[1-9]\d{0,2}$/, message: '优先级应为1-999的数字', trigger: 'blur'} |
|||
], |
|||
checkedKeys: [ |
|||
{ |
|||
required: true, |
|||
message: '请选择权限列表', |
|||
trigger: 'change', // 选框变化或提交时触发,可根据实际调整 |
|||
validator: (rule, value, callback) => { |
|||
if (value && value.length > 0) { |
|||
callback(); // 有选中项,校验通过 |
|||
} else { |
|||
callback(new Error('请选择权限列表')); // 未选中,抛出错误提示 |
|||
} |
|||
} |
|||
} |
|||
] |
|||
}); |
|||
|
|||
const throttledHandleAddRole = _.throttle(handleAddRole, 5000, { |
|||
trailing: false |
|||
}) |
|||
|
|||
// 挂载 |
|||
onMounted(async function () { |
|||
await getAdminData() |
|||
await get() |
|||
await getArea() |
|||
await getStore() |
|||
await getRoleList() |
|||
await getRolePermission() |
|||
await getRoleArea() |
|||
}) |
|||
|
|||
</script> |
|||
<template> |
|||
<div> |
|||
<!-- 角色搜索 --> |
|||
<el-card style="margin-bottom: 20px"> |
|||
<div class="head-card"> |
|||
<el-text class="mx-1" size="large">角色名称:</el-text> |
|||
<el-input v-model="role.name" style="width: 240px" placeholder="请输入角色名称" clearable/> |
|||
<div class="head-card-btn"> |
|||
<el-button type="success" @click="reset()">重置</el-button> |
|||
<el-button type="primary" @click="searchRole()">查询</el-button> |
|||
</div> |
|||
</div> |
|||
</el-card> |
|||
<!-- 展示表单 --> |
|||
<el-card> |
|||
|
|||
<div class="add-item"> |
|||
<el-button style="color: #048efb; border: 1px solid #048efb" @click="permissionAddInit()">新增角色</el-button> |
|||
</div> |
|||
<div> |
|||
<el-table :data="roleData" style="width: 100%" show-overflow-tooltip> |
|||
<el-table-column type="index" label="序号" width="100px" fixed="left"> |
|||
<template #default="scope"> |
|||
<span>{{ |
|||
scope.$index + 1 + (getRoleObj.pageNum - 1) * getRoleObj.pageSize |
|||
}}</span> |
|||
</template> |
|||
</el-table-column> |
|||
|
|||
<el-table-column prop="roleName" label="角色名称"/> |
|||
<el-table-column prop="fatherName" label="上级角色"/> |
|||
<el-table-column prop="priority" label="优先级"/> |
|||
<el-table-column label="权限范围" show-overflow-tooltip> |
|||
<template #default="scope"> |
|||
<div class="permission-cell" @click="showMenuTree(scope.row.tree, scope.row.roleName)"> |
|||
{{ formatPermissions(scope.row.tree) }} |
|||
</div> |
|||
</template> |
|||
</el-table-column> |
|||
<!-- <el-table-column prop="operation" label="操作" width="200px"> |
|||
<template #default="scope"> |
|||
<el-popconfirm title="确定将此角色删除吗?" @confirm="delRoleConfirm"> |
|||
<template #reference> |
|||
<el-button type="danger" text @click="delRole(scope.row)" |
|||
:disabled="scope.row.id === 1 || scope.row.id === 2"> |
|||
删除 |
|||
</el-button> |
|||
</template> |
|||
<template #actions="{ confirm, cancel }"> |
|||
<el-button size="small" @click="cancel">取消</el-button> |
|||
<el-button type="primary" size="small" @click="confirm"> |
|||
确定 |
|||
</el-button> |
|||
</template> |
|||
</el-popconfirm> |
|||
</template> |
|||
</el-table-column> --> |
|||
<el-table-column prop="operation" label="操作" width="200px"> |
|||
<template #default="scope"> |
|||
<el-button type="warning" text @click="permissionEditRoleInit(scope.row)" :disabled="scope.row.id === 2"> |
|||
编辑 |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
|
|||
<!-- 分页 --> |
|||
<div class="pagination" style="margin-top: 20px"> |
|||
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]" |
|||
layout="total, sizes, prev, pager, next, jumper" :total="roleTotal" |
|||
@size-change="handleRolePageSizeChange" |
|||
@current-change="handleRoleCurrentChange"></el-pagination> |
|||
</div> |
|||
</el-card> |
|||
</div> |
|||
<!-- 角色菜单树展示 --> |
|||
<el-dialog v-model="menuTreeVisible" :title='`权限详情:${currentRoleName}`' width="600px"> |
|||
<el-tree :data="currentRoleMenuTree" node-key="id" :props="{ label: 'menuName', children: 'children' }" |
|||
show-checkbox check-strictly :expand-on-click-node="false" |
|||
:default-expanded-keys="currentRoleMenuTree.map(item => item.id)" :default-checked-keys="Rolecheckedkeys"/> |
|||
<template #footer> |
|||
<el-button @click="menuTreeVisible = false" type="primary">关闭</el-button> |
|||
</template> |
|||
</el-dialog> |
|||
|
|||
<!-- 新增角色 --> |
|||
<el-dialog v-model="permissionAddVisible" title="新增角色" width="800px" :close-on-click-modal="false"> |
|||
<template #footer> |
|||
<el-form ref="Ref" :rules="Rolerules" :model="addRole" label-width="auto" |
|||
style="max-width: 600px; align-items: center"> |
|||
<el-form-item prop="roleName" label="角色名称:" required> |
|||
<el-input v-model="addRole.roleName" placeholder="请输入用户名" style="width: 220px"/> |
|||
</el-form-item> |
|||
<el-form-item prop="parentName" label="上级角色:"> |
|||
<el-select v-model="addRole.parentId" placeholder="请选择上级角色" style="width: 220px" @change="getLists" |
|||
clearable> |
|||
<el-option v-for="item in permissionList" :key="item.value" :label="item.label" |
|||
:value="item.value"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item prop="market" label="所属地区:" required> |
|||
<el-select v-model="addRole.market" placeholder="请选择所属地区" style="width: 240px" clearable> |
|||
<el-option v-for="item in addRoleMarket" :key="item" :label="item" :value="item"/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item prop="checkedKeys" label="权限列表:" required> |
|||
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" |
|||
:props="{ label: 'menuName', children: 'children' }" :checked-keys="addRole.checkedKeys" |
|||
:check-strictly="false" |
|||
@check="handleCheckChange"> |
|||
<template #default="{ node, data }"> |
|||
<span>{{ node.label }}</span> |
|||
</template> |
|||
</el-tree> |
|||
<div v-else style="display: flex; align-items: center; gap: 8px;"> |
|||
<span style="color: #999;">暂无数据</span> |
|||
</div> |
|||
</el-form-item> |
|||
<el-form-item prop="grade" label="优先级:" required> |
|||
<el-input v-model="addRole.grade" placeholder="数字1~999" style="width: 220px"/> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<div> |
|||
<el-button @click="closePermissionAddVisible()">取消</el-button> |
|||
<el-button type="primary" @click="throttledHandleAddRole"> |
|||
提交 |
|||
</el-button> |
|||
</div> |
|||
</template> |
|||
</el-dialog> |
|||
<!-- 編輯角色彈窗 --> |
|||
<el-dialog v-model="permissionEditRoleVisible" title="编辑角色" width="800px" :close-on-click-modal="false"> |
|||
<template #footer> |
|||
<el-form ref="Ref" :rules="Rolerules" :model="permissionEditRoleObj" label-width="auto" |
|||
style="max-width: 600px; align-items: center"> |
|||
<el-form-item prop="roleName" label="角色名称:" required> |
|||
<el-input v-model="permissionEditRoleObj.roleName" placeholder="请输入角色名称" style="width: 220px"/> |
|||
</el-form-item> |
|||
<el-form-item prop="parentName" label="上级角色:"> |
|||
<el-input v-model="permissionEditRoleObj.parentName" placeholder="无上级角色" disabled style="width: 220px"> |
|||
<el-option v-for="item in permissionList" :key="item.value" :label="item.label" |
|||
:value="item.value"></el-option> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item prop="market" label="地区" required> |
|||
<el-input v-model="permissionEditRoleObj.market" placeholder="请输入所属地区" style="width: 220px" disabled/> |
|||
</el-form-item> |
|||
<el-form-item prop="checkedKeys" label="权限列表:" required> |
|||
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" ref="treeRef" |
|||
:props="{ label: 'menuName', children: 'children' }" |
|||
:default-checked-keys="permissionEditRoleObj.checkedKeys" |
|||
:check-strictly="false" |
|||
@check="handleEditRolePermissionCheck"> |
|||
<template #default="{ node, data }"> |
|||
<span>{{ node.label }}</span> |
|||
</template> |
|||
</el-tree> |
|||
<div v-else style="display: flex; align-items: center; gap: 8px;"> |
|||
<span style="color: #999;">暂无数据</span> |
|||
</div> |
|||
</el-form-item> |
|||
<!-- <el-form-item prop="grade" label="优先级:" required> |
|||
<el-input v-model="permissionEditRoleObj.grade" placeholder="数字1~999" style="width: 220px" /> |
|||
</el-form-item> --> |
|||
</el-form> |
|||
|
|||
<div> |
|||
<el-button @click="permissionEditRoleVisible = false">取消</el-button> |
|||
<el-button type="primary" @click="permissionEditRole"> |
|||
提交 |
|||
</el-button> |
|||
</div> |
|||
</template> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.pagination { |
|||
display: flex; |
|||
} |
|||
|
|||
|
|||
.head-card { |
|||
display: flex; |
|||
} |
|||
|
|||
.head-card-btn { |
|||
margin-left: auto; |
|||
} |
|||
|
|||
|
|||
.permission-cell { |
|||
cursor: pointer; |
|||
color: #409eff; |
|||
/* 蓝色文字,提示可点击 */ |
|||
} |
|||
</style> |
1032
src/views/permissions/userPermission.vue
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue