index.vue 11.4 KB
<style lang="scss">
</style>

<template>
    <div class="app-container ">
        <section class="qg-container">
            <h4 class="qg-container__title">菜单管理
                <small style="font-weight: normal;color: #888;font-size: 12px">最多添加{{ maxLevel }}级菜单</small>
            </h4>
            <el-input
                v-model.trim="filterText"
                placeholder="输入关键字进行过滤"
            />
            <div class="qg-menu-header">
                <div class="qg-menu-name">菜单</div>
                <div class="qg-menu-icon">图标</div>
                <div class="qg-menu-code">权限码</div>
                <div class="qg-menu-route">路由地址</div>
                <div class="qg-menu-auths">功能权限</div>
                <div class="qg-menu-opt-bar">操作</div>
            </div>
            <el-tree
                ref="tree"
                class="qg-menu-tree filter-tree"
                :props="{children:'childList',label:'name'}"
                :data="menuData"
                :draggable="true"
                node-key="id"
                :expand-on-click-node="false"
                :default-expanded-keys="defaultExpandedKeys"
                :filter-node-method="filterNode"
                :allow-drop="allowDrop"
                @node-drop="handleDrop"
                @node-expand="addDefaultExpandedKeys"
                @node-collapse="removeDefaultExpandedKeys"
            >
                <div slot-scope="{ node, data }" :class="`qg-menu-tree-node${data.hide?' disabled':''}`">
                    <div class="qg-menu-name" :style="`width: ${300-(node.level-1)*18}px`">{{ data.name }}</div>
                    <div class="qg-menu-icon">
                        <svg-icon v-if="data.icon" :icon-class="data.icon"/>
                    </div>
                    <div class="qg-menu-code">
                        <div class="qg-text--ellipsis" :title="data.code">
                            {{ data.code }}
                        </div>
                    </div>
                    <div class="qg-menu-route">
                        <div class="qg-text--ellipsis" :title="data.routeUrl">
                            {{ data.routeUrl }}
                        </div>
                    </div>
                    <div class="qg-menu-auths">
                        <div class="qg-text--ellipsis">
                            <qg-button icon="el-icon-s-grid" tool-tip="功能权限" @click="openAuthCode(data)"/>
                            <template v-if="data.buttonList">
                                <span v-for="(item,index) in data.buttonList" :key="index">{{ index===0?'':'、' }}{{
                                    item.name }}
                                </span>
                            </template>
                        </div>
                    </div>
                    <div class="qg-menu-opt-bar">
                        <qg-button
                            v-if="node.level<maxLevel+1"
                            icon="el-icon-plus"
                            tool-tip="新增子菜单"
                            @click="handleAdd(node,data)"
                        />
                        <qg-button
                            v-if="data.id !== '*'"
                            tool-tip="编辑"
                            icon="el-icon-edit"
                            @click="handleEdit(node,data)"
                        />
                        <qg-button
                            v-if=" data.id !=='*' && (!data.childList || !data.buttonList)"
                            tool-tip="删除"
                            icon="el-icon-delete"
                            @click="handleDel(node,data)"
                        />
                        <qg-button
                            v-if="data.id !=='*'"
                            tool-tip="移动"
                            icon="el-icon-rank"
                        />
                    </div>
                </div>
            </el-tree>
        </section>
    </div>
</template>

<script>
    import {
        getAuthTree,
        authDelete,
        authMove
    } from '@/api/moudles/uc/auth';
    import menuEditDialog from './edit.vue';
    import AuthCode from './auth-code.vue';
    import {checkNodesPathIsHide} from './menu.js';

    // import checkPermission from '@/utils/permission';

    function getLevel(data, level) {
        if (!data.childList) {
            return level + 1;
        }
        const levels = [];
        data.childList.forEach(item => {
            levels.push(getLevel(item, level + 1));
        });
        return Math.max.apply(this, levels);
    }

    export default {
        name: 'Menu',
        components: {},
        filters: {},
        data() {
            return {
                menuIdPath: '',
                filterText: '',
                menuData: [],
                maxLevel: 3,
                userId: this.$store.getters.userId,
                defaultExpandedKeys: ['*']
            };
        },
        watch: {
            filterText(val) {
                this.$refs.tree.filter(val);
            }
        },
        created() {
            this.getDetail();
        },
        methods: {
            getDetail() {
                getAuthTree().then(res => {
                    if (res.success && res.data) {
                        const data = [res.data];
                        this.transMenuData(data);
                        this.menuData = data;
                        console.log(this.menuIdPath);
                        // 获取菜单管理id全路径
                        if (this.filterText.trim()) {
                            this.$nextTick(() => {
                                this.$refs.tree.filter(this.filterText);
                            });
                        }
                    } else {
                        this.menuData = [];
                    }
                });
            },
            transMenuData(data, parent) {
                data.forEach(item => {
                    item.idPath = (parent ? parent.idPath + ',' : '') + item.id;
                    if (item.code === 'menu') {
                        this.menuIdPath = item.idPath;
                    }
                    if (item.childList) {
                        this.transMenuData(item.childList, item);
                    }
                });
            },
            filterNode(value, data) {
                if (!value) {
                    return true;
                }
                return data.name.indexOf(value) !== -1;
            },
            handleEditSuccess() {
                this.getDetail();
            },
            handleAdd(node, data) {
                if (node.childNodes.length > 50) {
                    this.$message.warning('子菜单已超过50个,为了系统体验不允许继续添加!');
                    return;
                }
                const entity = {
                    pId: data.id,
                    pName: data.name,
                    name: '',
                    code: data.code,
                    appCode: data.appCode,
                    manage: true,
                    url: data.url,
                    routeUrl: data.routeUrl,
                    openWay: 'default',
                    linkType: 'inner',
                    menu: true,
                    hide: data.hide,
                    icon: ''
                };
                const dialog = this.$qgDialog({
                    title: '新增',
                    width: '800px',
                    component: menuEditDialog,
                    props: {
                        entity: entity,
                        callback: () => {
                            dialog.close();
                            this.handleEditSuccess();
                        }
                    }
                });
            },
            handleEdit(node, data) {
                const entity = {...data, pName: node.parent.data.name, pId: data.pid};
                const menuIdPath = this.menuIdPath;
                const dialog = this.$qgDialog({
                    title: '编辑',
                    width: '800px',
                    component: menuEditDialog,
                    props: {
                        entity: entity,
                        menuIdPath,
                        callback: () => {
                            dialog.close();
                            this.handleEditSuccess();
                        }
                    }
                });
            },
            handleDel(node, data) {
                let tips = '';
                if (data.child) {
                    tips = '当前节点存在子节点,';
                }
                tips += '确定要删除该数据吗?';
                this.$confirm(tips, {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    authDelete(data.id).then(result => {
                        this.handleEditSuccess();
                        this.$message.success('删除成功');
                        this.removeDefaultExpandedKeys(data);
                    });
                });
            },
            handleDrop(draggingNode, dropNode, dropType, ev) {
                const dropNodeData = dropNode.data;
                const id = draggingNode.data.id;
                let pId = '';
                let preId = '';
                let nextId = '';
                pId = dropNodeData.pid;
                switch (dropType) {
                    case 'before':
                        nextId = dropNodeData.id;
                        break;
                    case 'after':
                        preId = dropNodeData.id;
                        break;
                    case 'inner':
                        pId = dropNodeData.id;
                        break;
                }
                authMove({id, pId, preId, nextId}).then(res => {
                    this.handleEditSuccess();
                    if (res.success) {
                        this.$message.success('移动成功');
                    } else {
                        this.$message.error('移动失败');
                    }
                });
            },
            allowDrop(draggingNode, dropNode, type) {
                const level = getLevel(draggingNode.data, 0);
                if (type === 'inner' &&
                    checkNodesPathIsHide(dropNode) &&
                    this.menuIdPath.split(',').indexOf(draggingNode.data.id) > -1) {
                    return false;
                }

                return !(dropNode.level + level > this.maxLevel && type === 'inner');
            },
            addDefaultExpandedKeys(data) {
                this.defaultExpandedKeys.push(data.id);
            },
            removeDefaultExpandedKeys(data) {
                const index = this.defaultExpandedKeys.indexOf(data.id);
                this.defaultExpandedKeys.splice(index, 1);
            },
            openAuthCode(data) {
                this.$qgDialog({
                    title: '编辑',
                    width: '800px',
                    props: {
                        data: data
                    },
                    component: AuthCode,
                    beforeClose: () => {
                        this.handleEditSuccess();
                    }
                });
            }
        }
    };
</script>