|
@@ -0,0 +1,404 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <el-row :gutter="10" class="mb8 czBtns">
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handelAdd">添加菜单权限</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button
|
|
|
+ type="danger"
|
|
|
+ plain
|
|
|
+ icon="el-icon-delete-solid"
|
|
|
+ size="mini"
|
|
|
+ :disabled="celDistribution"
|
|
|
+ @click="handleDelMenus"
|
|
|
+ >批量取消
|
|
|
+ </el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="warning" plain icon="el-icon-back" size="mini" @click="handleClose">返回</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-table
|
|
|
+ ref="roleTable"
|
|
|
+ v-loading="loading"
|
|
|
+ :data="menuList"
|
|
|
+ row-key="id"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ header-row-class-name="headBackground"
|
|
|
+ @selection-change="handelDelDist"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="55" align="center" />
|
|
|
+ <el-table-column label="菜单名称" prop="menuName" header-align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="菜单图标" prop="menuIcon" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="菜单路径" prop="menuUrl" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="更新时间" prop="updateTime" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="创建时间" prop="createTime" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="mini" :disabled="!celDistribution" @click="delMenu(scope.row.id)"><i
|
|
|
+ class="el-icon-circle-close celBtn"
|
|
|
+ /><span>取消分配</span>
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <el-dialog title="添加菜单权限" :visible.sync="dialogVisible" width="800px" :close-on-click-modal="false">
|
|
|
+ <el-row class="czBtns">
|
|
|
+ <el-col>
|
|
|
+ <el-button type="primary" plain icon="el-icon-plus" size="mini" :disabled="distribution" @click="handleDel">
|
|
|
+ 批量分配</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-table
|
|
|
+ ref="distTable"
|
|
|
+ v-loading="distLoading"
|
|
|
+ :data="addMenuList"
|
|
|
+ row-key="id"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ header-row-class-name="headBackground"
|
|
|
+ :expand-row-keys="defaultExpend"
|
|
|
+ @selection-change="handelAddDist"
|
|
|
+ @select="select"
|
|
|
+ @select-all="selectAll"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="55" align="center" />
|
|
|
+ <el-table-column label="菜单名称" prop="menuName" header-align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="菜单图标" prop="menuIcon" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="菜单路径" prop="menuUrl" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ icon="el-icon-circle-plus"
|
|
|
+ size="mini"
|
|
|
+ :disabled="!distribution"
|
|
|
+ @click="addMenu(scope.row.id, $event)"
|
|
|
+ >分配菜单
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getMenuListByRoleId, getMenuListTree, distributionMenu, delDistributionMenu } from '@/api/system/role'
|
|
|
+export default {
|
|
|
+ name: 'UserMenu',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 遮罩层
|
|
|
+ loading: true,
|
|
|
+ // 弹出框表格加载状态
|
|
|
+ distLoading: true,
|
|
|
+ // 角色ID
|
|
|
+ roleId: null,
|
|
|
+ // 分配菜单参数
|
|
|
+ distObj: {
|
|
|
+ id: this.$route.params.userId,
|
|
|
+ menuList: []
|
|
|
+ },
|
|
|
+ // 取消分配菜单参数
|
|
|
+ delDistObj: {
|
|
|
+ id: this.$route.params.userId,
|
|
|
+ menuList: []
|
|
|
+ },
|
|
|
+ // 用户表格数据
|
|
|
+ menuList: [],
|
|
|
+ // 禁用取消分配
|
|
|
+ celDistribution: true,
|
|
|
+ // 弹出框
|
|
|
+ dialogVisible: false,
|
|
|
+ // 分配菜单表格
|
|
|
+ addMenuList: [],
|
|
|
+ // 禁用分配
|
|
|
+ distribution: true,
|
|
|
+ // 全选按钮选中所有节点
|
|
|
+ isSelectAll: false,
|
|
|
+ // 默认展开行
|
|
|
+ defaultExpend: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.roleId = this.$route.params.userId
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /** 查询用户拥有的菜单列表 */
|
|
|
+ getList() {
|
|
|
+ const roleList = []
|
|
|
+ roleList.push({ id: Number(this.$route.params.userId) })
|
|
|
+ getMenuListByRoleId({ roleList }).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ const data = res.data
|
|
|
+ this.menuList = this.$utils.toArrayTree(data)
|
|
|
+ this.loading = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 所有菜单树信息 */
|
|
|
+ getMenuListTree() {
|
|
|
+ getMenuListTree().then(res => {
|
|
|
+ const data = res.data
|
|
|
+ data.forEach(item => {
|
|
|
+ item.isSelect = false
|
|
|
+ })
|
|
|
+ this.addMenuList = data
|
|
|
+ console.log(this.addMenuList)
|
|
|
+ this.distLoading = false
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.defaultExpend = []
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 返回按钮 */
|
|
|
+ handleClose() {
|
|
|
+ this.$router.push('/system/role')
|
|
|
+ },
|
|
|
+ /** 添加菜单 */
|
|
|
+ handelAdd() {
|
|
|
+ this.dialogVisible = true
|
|
|
+ this.getMenuListTree()
|
|
|
+ },
|
|
|
+ /** 分配菜单多选 */
|
|
|
+ handelAddDist(selection) {
|
|
|
+ this.distObj.menuList = selection.map(item => { return { id: item.id } })
|
|
|
+ this.distribution = !selection.length
|
|
|
+ },
|
|
|
+ /** 取消分配菜单多选 */
|
|
|
+ handelDelDist(selection) {
|
|
|
+ this.delDistObj.menuList = selection.map(item => { return { id: item.id } })
|
|
|
+ this.celDistribution = !selection.length
|
|
|
+ },
|
|
|
+ /** 分配按钮 */
|
|
|
+ addMenu(id, event) {
|
|
|
+ this.$resetBtn(event)
|
|
|
+ this.distObj.menuList = []
|
|
|
+ this.$confirm('您确定要分配该菜单吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ cancelButtonClass: 'btn_custom_cancel',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.distObj.menuList.push({ id })
|
|
|
+ this.distributionMenu()
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message({
|
|
|
+ type: 'info',
|
|
|
+ message: '已取消操作'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 批量分配菜单按钮 */
|
|
|
+ handleDel(event) {
|
|
|
+ this.$resetBtn(event)
|
|
|
+ this.$confirm('您确定要批量分配选中的菜单吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ cancelButtonClass: 'btn_custom_cancel',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.distributionMenu()
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message({
|
|
|
+ type: 'info',
|
|
|
+ message: '已取消操作'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 取消分配按钮 */
|
|
|
+ delMenu(id) {
|
|
|
+ this.delDistObj.menuList = []
|
|
|
+ this.$confirm('您确定要取消分配该菜单吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ cancelButtonClass: 'btn_custom_cancel',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.delDistObj.menuList.push({ id })
|
|
|
+ this.delDistributionMenu()
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message({
|
|
|
+ type: 'info',
|
|
|
+ message: '已取消操作'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 批量取消分配菜单按钮 */
|
|
|
+ handleDelMenus() {
|
|
|
+ this.$confirm('您确定要批量取消选中的菜单吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ cancelButtonClass: 'btn_custom_cancel',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.delDistributionMenu()
|
|
|
+ }).catch(() => {
|
|
|
+ this.$refs.roleTable.clearSelection()
|
|
|
+ this.$message({
|
|
|
+ type: 'info',
|
|
|
+ message: '已取消操作'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 分配菜单请求 */
|
|
|
+ distributionMenu() {
|
|
|
+ distributionMenu(this.distObj).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message({
|
|
|
+ type: 'success',
|
|
|
+ message: res.data
|
|
|
+ })
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.getList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 取消分配菜单请求 */
|
|
|
+ delDistributionMenu() {
|
|
|
+ delDistributionMenu(this.delDistObj).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message({
|
|
|
+ type: 'success',
|
|
|
+ message: '取消成功'
|
|
|
+ })
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.getList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 选中父节点时,子节点一起选中取消
|
|
|
+ select(selection, row) {
|
|
|
+ // 选中
|
|
|
+ if (
|
|
|
+ selection.some((el) => {
|
|
|
+ return row.id === el.id
|
|
|
+ })
|
|
|
+ ) {
|
|
|
+ // 选中行有children
|
|
|
+ if (row.children.length) {
|
|
|
+ // 全选children
|
|
|
+ this.setChildren(row.children, true)
|
|
|
+ } else {
|
|
|
+ this.findParentNode(this.addMenuList, selection, row)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 反选
|
|
|
+ // 子节点有children全选中
|
|
|
+ if (row.children.length) {
|
|
|
+ this.setChildren(row.children, false)
|
|
|
+ } else {
|
|
|
+ // 反选子节点反选父节点
|
|
|
+ const parentRow = selection.find(item => {
|
|
|
+ return item.id === row.parentId
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.distTable.toggleRowSelection(parentRow, false)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ findParentNode(data, selection, row) {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ this.setParentCheck(data[i], selection, row)
|
|
|
+ if (data[i].children) {
|
|
|
+ this.findParentNode(data[i].children, selection, row)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setParentCheck(item, selection, row) {
|
|
|
+ if (item.id === row.parentId) {
|
|
|
+ const selectIds = selection.filter(o => {
|
|
|
+ return item.id === o.parentId
|
|
|
+ })
|
|
|
+ if (item.children.length === 1) {
|
|
|
+ this.recursion(this.addMenuList, item)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ item.children.forEach(j => {
|
|
|
+ selectIds.forEach(q => {
|
|
|
+ if (j.id === q.id) {
|
|
|
+ if (selectIds.length === item.children.length) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.distTable.toggleRowSelection(item, true)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ recursion(data, item) {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ if (item) {
|
|
|
+ if (data[i].id === item.parentId) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.distTable.toggleRowSelection(data[i], true)
|
|
|
+ this.$refs.distTable.toggleRowSelection(item, true)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (data[i].children) {
|
|
|
+ this.recursion(data[i].children)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 选择全部
|
|
|
+ selectAll(selection) {
|
|
|
+ // addMenuList第一层只要有在selection里面就是全选
|
|
|
+ const isSelect = selection.some((el) => {
|
|
|
+ const tableDataIds = this.addMenuList.map((j) => j.id)
|
|
|
+ return tableDataIds.includes(el.id)
|
|
|
+ })
|
|
|
+ // addMenuList第一层只要有不在selection里面就是全不选
|
|
|
+ const isCancel = !this.addMenuList.every((el) => {
|
|
|
+ const selectIds = selection.map((j) => j.id)
|
|
|
+ return selectIds.includes(el.id)
|
|
|
+ })
|
|
|
+ if (isSelect) {
|
|
|
+ selection.map((el) => {
|
|
|
+ if (el.children) {
|
|
|
+ // 解决子节点没有被勾选到
|
|
|
+ this.setChildren(el.children, true)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (isCancel) {
|
|
|
+ this.addMenuList.map((el) => {
|
|
|
+ if (el.children) {
|
|
|
+ // 解决子节点没有被勾选到
|
|
|
+ this.setChildren(el.children, false)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setChildren(children, type) {
|
|
|
+ // 编辑多个子节点
|
|
|
+ children.map((j) => {
|
|
|
+ this.toggleSelection(j, type)
|
|
|
+ if (j.children) {
|
|
|
+ this.setChildren(j.children, type)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ toggleSelection(row, select) {
|
|
|
+ if (row) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.distTable.toggleRowSelection(row, select)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+
|
|
|
+</style>
|