|
|
|
@ -1,5 +1,8 @@
|
|
|
|
|
<template>
|
|
|
|
|
<!-- 使用 el-card 组件创建一个表单容器卡片,设置阴影效果为无 -->
|
|
|
|
|
<el-card class="form-container" shadow="never">
|
|
|
|
|
<!-- el-tree 组件,用于展示树形结构的数据,绑定了 menuTreeList 数据作为树的数据源 -->
|
|
|
|
|
<!-- 显示复选框,默认展开所有节点,设置节点的唯一标识键为 'id',添加了引用名 'tree',高亮当前选中节点,并配置了节点属性映射 -->
|
|
|
|
|
<el-tree
|
|
|
|
|
:data="menuTreeList"
|
|
|
|
|
show-checkbox
|
|
|
|
@ -9,93 +12,126 @@
|
|
|
|
|
highlight-current
|
|
|
|
|
:props="defaultProps">
|
|
|
|
|
</el-tree>
|
|
|
|
|
<!-- 包含两个按钮的 div 容器,设置了顶部外边距为 20px,并使其内容居中对齐 -->
|
|
|
|
|
<div style="margin-top: 20px" align="center">
|
|
|
|
|
<!-- 保存按钮,类型为主要(primary),点击时调用 handleSave 方法 -->
|
|
|
|
|
<el-button type="primary" @click="handleSave()">保存</el-button>
|
|
|
|
|
<!-- 清空按钮,点击时调用 handleClear 方法 -->
|
|
|
|
|
<el-button @click="handleClear()">清空</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {fetchTreeList} from '@/api/menu';
|
|
|
|
|
import {listMenuByRole,allocMenu} from '@/api/role';
|
|
|
|
|
// 从 @/api/menu 模块中导入获取树形菜单列表数据的 API 函数
|
|
|
|
|
import {fetchTreeList} from '@/api/menu';
|
|
|
|
|
// 从 @/api/role 模块中导入根据角色获取菜单列表以及分配菜单的 API 函数
|
|
|
|
|
import {listMenuByRole, allocMenu} from '@/api/role';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "allocMenu",
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
menuTreeList: [],
|
|
|
|
|
defaultProps: {
|
|
|
|
|
children: 'children',
|
|
|
|
|
label: 'title'
|
|
|
|
|
},
|
|
|
|
|
roleId:null
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.roleId = this.$route.query.roleId;
|
|
|
|
|
this.treeList();
|
|
|
|
|
this.getRoleMenu(this.roleId);
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
treeList() {
|
|
|
|
|
fetchTreeList().then(response => {
|
|
|
|
|
this.menuTreeList = response.data;
|
|
|
|
|
});
|
|
|
|
|
export default {
|
|
|
|
|
name: "allocMenu",
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
// 用于存储树形菜单列表数据,初始值为空数组,后续通过 API 获取并赋值
|
|
|
|
|
menuTreeList: [],
|
|
|
|
|
// 配置 el-tree 组件节点属性的映射对象,指定子节点属性名为 'children',节点显示文本对应的属性名为 'title'
|
|
|
|
|
defaultProps: {
|
|
|
|
|
children: 'children',
|
|
|
|
|
label: 'title'
|
|
|
|
|
},
|
|
|
|
|
getRoleMenu(roleId){
|
|
|
|
|
listMenuByRole(roleId).then(response=>{
|
|
|
|
|
let menuList = response.data;
|
|
|
|
|
let checkedMenuIds=[];
|
|
|
|
|
if(menuList!=null&&menuList.length>0){
|
|
|
|
|
for(let i=0;i<menuList.length;i++){
|
|
|
|
|
let menu = menuList[i];
|
|
|
|
|
if(menu.parentId!==0){
|
|
|
|
|
checkedMenuIds.push(menu.id);
|
|
|
|
|
}
|
|
|
|
|
// 存储当前操作的角色 ID,初始值为 null,后续从路由参数中获取赋值
|
|
|
|
|
roleId: null
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
// 从路由参数中获取角色 ID,并赋值给 roleId 属性,用于后续相关操作的参数传递等
|
|
|
|
|
this.roleId = this.$route.query.roleId;
|
|
|
|
|
// 调用获取树形菜单列表数据的方法,用于初始化页面上的树形菜单展示
|
|
|
|
|
this.treeList();
|
|
|
|
|
// 调用根据角色获取菜单列表的方法,传入获取到的角色 ID,用于后续设置已选中的菜单节点等操作
|
|
|
|
|
this.getRoleMenu(this.roleId);
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
treeList() {
|
|
|
|
|
// 调用获取树形菜单列表数据的 API 函数,该函数返回一个 Promise,成功获取数据后将响应数据中的菜单列表赋值给 menuTreeList 属性,用于在 el-tree 组件中展示树形菜单结构
|
|
|
|
|
fetchTreeList().then(response => {
|
|
|
|
|
this.menuTreeList = response.data;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
getRoleMenu(roleId) {
|
|
|
|
|
// 调用根据角色获取菜单列表的 API 函数,传入角色 ID,该函数返回一个 Promise,成功获取数据后进行如下处理
|
|
|
|
|
listMenuByRole(roleId).then(response => {
|
|
|
|
|
// 获取到的菜单列表数据赋值给 menuList 变量,方便后续操作
|
|
|
|
|
let menuList = response.data;
|
|
|
|
|
// 用于存储已选中的菜单 ID 的数组,初始为空
|
|
|
|
|
let checkedMenuIds = [];
|
|
|
|
|
// 判断菜单列表不为空且有数据时,进行循环遍历
|
|
|
|
|
if (menuList!= null && menuList.length > 0) {
|
|
|
|
|
for (let i = 0; i < menuList.length; i++) {
|
|
|
|
|
// 取出每一个菜单对象
|
|
|
|
|
let menu = menuList[i];
|
|
|
|
|
// 如果菜单的上级菜单 ID 不等于 0(意味着不是顶级菜单,可能是需要关注的子菜单等情况),将其 ID 添加到已选中菜单 ID 数组中
|
|
|
|
|
if (menu.parentId!== 0) {
|
|
|
|
|
checkedMenuIds.push(menu.id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.$refs.tree.setCheckedKeys(checkedMenuIds);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleSave() {
|
|
|
|
|
let checkedNodes = this.$refs.tree.getCheckedNodes();
|
|
|
|
|
let checkedMenuIds=new Set();
|
|
|
|
|
if(checkedNodes!=null&&checkedNodes.length>0){
|
|
|
|
|
for(let i=0;i<checkedNodes.length;i++){
|
|
|
|
|
let checkedNode = checkedNodes[i];
|
|
|
|
|
checkedMenuIds.add(checkedNode.id);
|
|
|
|
|
if(checkedNode.parentId!==0){
|
|
|
|
|
checkedMenuIds.add(checkedNode.parentId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 通过 el-tree 组件的引用(通过 ref='tree' 获取),设置已选中的节点对应的菜单 ID 数组,用于在页面上展示对应角色已分配的菜单节点为选中状态
|
|
|
|
|
this.$refs.tree.setCheckedKeys(checkedMenuIds);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleSave() {
|
|
|
|
|
// 获取 el-tree 组件中当前被选中的所有节点,这些节点包含了菜单相关的详细信息
|
|
|
|
|
let checkedNodes = this.$refs.tree.getCheckedNodes();
|
|
|
|
|
// 使用 Set 数据结构来存储选中菜单的 ID,用于去重(避免重复添加相同的菜单 ID)
|
|
|
|
|
let checkedMenuIds = new Set();
|
|
|
|
|
// 判断获取到的选中节点不为空且有数据时,进行循环遍历
|
|
|
|
|
if (checkedNodes!= null && checkedNodes.length > 0) {
|
|
|
|
|
for (let i = 0; i < checkedNodes.length; i++) {
|
|
|
|
|
// 取出每一个选中的节点对象
|
|
|
|
|
let checkedNode = checkedNodes[i];
|
|
|
|
|
// 将选中节点的 ID 添加到 Set 集合中
|
|
|
|
|
checkedMenuIds.add(checkedNode.id);
|
|
|
|
|
// 如果选中节点的上级菜单 ID 不等于 0(同样考虑到相关联的上级菜单也需要处理等情况),将上级菜单 ID 也添加到 Set 集合中
|
|
|
|
|
if (checkedNode.parentId!== 0) {
|
|
|
|
|
checkedMenuIds.add(checkedNode.parentId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.$confirm('是否分配菜单?', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(()=>{
|
|
|
|
|
let params = new URLSearchParams();
|
|
|
|
|
params.append("roleId",this.roleId);
|
|
|
|
|
params.append("menuIds",Array.from(checkedMenuIds));
|
|
|
|
|
allocMenu(params).then(response => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '分配成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
this.$router.back();
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
handleClear() {
|
|
|
|
|
this.$refs.tree.setCheckedKeys([]);
|
|
|
|
|
}
|
|
|
|
|
// 弹出确认框,询问是否分配菜单,提供确定和取消按钮供用户选择
|
|
|
|
|
this.$confirm('是否分配菜单?', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
// 创建 URLSearchParams 对象,用于构建请求参数,通常用于向服务器传递数据
|
|
|
|
|
let params = new URLSearchParams();
|
|
|
|
|
// 将当前角色 ID 添加到请求参数中
|
|
|
|
|
params.append("roleId", this.roleId);
|
|
|
|
|
// 将处理后的选中菜单 ID 数组(通过 Array.from 转换为普通数组)添加到请求参数中
|
|
|
|
|
params.append("menuIds", Array.from(checkedMenuIds));
|
|
|
|
|
// 调用分配菜单的 API 函数,传入构建好的请求参数,该函数返回一个 Promise,成功分配菜单后进行如下处理
|
|
|
|
|
allocMenu(params).then(response => {
|
|
|
|
|
// 显示分配成功的提示消息,消息类型为成功(success),停留 1000 毫秒
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '分配成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
// 通过路由导航返回上一页,一般用于完成操作后回到之前的页面
|
|
|
|
|
this.$router.back();
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
handleClear() {
|
|
|
|
|
// 通过 el-tree 组件的引用,将已选中的节点对应的菜单 ID 数组设置为空数组,即清空所有已选中的菜单节点状态
|
|
|
|
|
this.$refs.tree.setCheckedKeys([]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
|
|
|
|
/* 当前 CSS 部分为空,可在此处添加针对当前组件(allocMenu 组件)的样式规则,
|
|
|
|
|
例如设置 el-tree 组件的样式,像节点的字体、颜色、间距等,以及按钮的样式,包括按钮的大小、颜色、边框等,
|
|
|
|
|
scoped 属性表示样式仅作用于当前组件内的元素,避免样式冲突 */
|
|
|
|
|
</style>
|
|
|
|
|