Procházet zdrojové kódy

菜单管理页样式修改

panhui před 7 roky
rodič
revize
1112cef48b

+ 1 - 1
src/main/vue/src/components/SubMenu.vue

@@ -243,7 +243,7 @@
         position: relative;
         position: relative;
         user-select: none;
         user-select: none;
         .icon {
         .icon {
-            margin-right: 6px;
+            margin-right:12px;
         }
         }
         .el-icon-arrow-left {
         .el-icon-arrow-left {
             position: absolute;
             position: absolute;

+ 13 - 12
src/main/vue/src/entries/admin.js

@@ -12,7 +12,7 @@ import VueAMap from 'vue-amap'
 import 'normalize.css/normalize.css'
 import 'normalize.css/normalize.css'
 import 'element-ui/lib/theme-chalk/index.css'
 import 'element-ui/lib/theme-chalk/index.css'
 import '../main.less'
 import '../main.less'
-import {format} from 'date-fns'
+import { format } from 'date-fns'
 import zh from 'date-fns/locale/zh_cn'
 import zh from 'date-fns/locale/zh_cn'
 
 
 VueAMap.initAMapApiLoader({
 VueAMap.initAMapApiLoader({
@@ -36,7 +36,7 @@ Vue.prototype.$http = {
     get(params) {
     get(params) {
         return new Promise((resolve, reject) => {
         return new Promise((resolve, reject) => {
             if (params instanceof String) {
             if (params instanceof String) {
-                params = {url: params};
+                params = { url: params };
             } else if (!params instanceof Object) {
             } else if (!params instanceof Object) {
                 reject('params error');
                 reject('params error');
                 return;
                 return;
@@ -84,7 +84,7 @@ Vue.prototype.$http = {
     },
     },
     post(params) {
     post(params) {
         if (params instanceof String) {
         if (params instanceof String) {
-            params = {url: params};
+            params = { url: params };
         } else if (!params instanceof Object) {
         } else if (!params instanceof Object) {
             reject('params error');
             reject('params error');
             return;
             return;
@@ -153,11 +153,11 @@ Vue.prototype.$http = {
 Vue.mixin({
 Vue.mixin({
     methods: {
     methods: {
         timeFormatter(row, column, cellValue, index) {
         timeFormatter(row, column, cellValue, index) {
-            return format(new Date(cellValue), 'HH:mm', {locale: zh})
+            return format(new Date(cellValue), 'HH:mm', { locale: zh })
         },
         },
         datetimeFormatter(row, column, cellValue, index) {
         datetimeFormatter(row, column, cellValue, index) {
             if (!cellValue) return '';
             if (!cellValue) return '';
-            return format(new Date(cellValue), 'YYYY/MM/DD HH:mm', {locale: zh})
+            return format(new Date(cellValue), 'YYYY/MM/DD HH:mm', { locale: zh })
         }
         }
     }
     }
 });
 });
@@ -165,6 +165,7 @@ Vue.mixin({
 const updateTableHeight = () => {
 const updateTableHeight = () => {
     try {
     try {
         const total = document.getElementsByTagName('main')[0].clientHeight;
         const total = document.getElementsByTagName('main')[0].clientHeight;
+        store.commit('updateAllHeight', total);
         const filter = document.getElementsByClassName('filters-container')[0].clientHeight;
         const filter = document.getElementsByClassName('filters-container')[0].clientHeight;
         const page = document.getElementsByClassName('pagination-wrapper')[0].clientHeight;
         const page = document.getElementsByClassName('pagination-wrapper')[0].clientHeight;
         store.commit('updateTableHeight', total - filter - page - 44);
         store.commit('updateTableHeight', total - filter - page - 44);
@@ -173,12 +174,13 @@ const updateTableHeight = () => {
     }
     }
 };
 };
 
 
-const debounce = function (idle, action) {
+const debounce = function(idle, action) {
     let last;
     let last;
-    return function () {
-        let ctx = this, args = arguments;
+    return function() {
+        let ctx = this,
+            args = arguments;
         clearTimeout(last);
         clearTimeout(last);
-        last = setTimeout(function () {
+        last = setTimeout(function() {
             action.apply(ctx, args)
             action.apply(ctx, args)
         }, idle)
         }, idle)
     }
     }
@@ -200,8 +202,7 @@ new Vue({
     router,
     router,
     store,
     store,
     components: {},
     components: {},
-    template:
-        `<keep-alive include="*">
+    template: `<keep-alive include="*">
             <router-view></router-view>
             <router-view></router-view>
         </keep-alive>`
         </keep-alive>`
-});
+});

+ 63 - 1
src/main/vue/src/main.less

@@ -64,7 +64,7 @@ ul, li {
 .el-pagination {
 .el-pagination {
     display: flex;
     display: flex;
     justify-content: center;
     justify-content: center;
-    background: #fff;
+    // background: #fff;
 }
 }
 
 
 .filters-container {
 .filters-container {
@@ -109,3 +109,65 @@ ul, li {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
 }
 }
+
+
+.head-tabs .el-tabs__header{
+    margin-bottom:0;
+    border:0;
+    .el-tabs__nav{
+        border:0;
+        border-right:1px solid #e4e7ed;
+        box-sizing:border-box;
+    }
+    .el-tabs__item{
+        color:#999;
+    }
+    .el-tabs__item.is-active{
+       border-bottom:2px solid #0096E0;
+       color:#0096E0;
+       box-sizing:border-box;
+    }
+    .el-tabs__item:hover{
+        background:rgba(235,238,240,1);
+        color:#999999;
+        border-bottom:2px solid #0096E0;
+        box-sizing:border-box;
+    }
+}
+
+
+.head-tabs{
+    .el-tabs__item .el-icon-close{
+        background-color: #ccc;
+    color: #fff;
+    line-height: 14px;
+
+    }
+    .el-tabs__item .el-icon-close:hover{
+        background-color: #FF3B30;
+        color: #fff;
+        border-right:1px solid #e4e7ed;
+        border-left:1px solid #e4e7ed;
+    }
+
+    .el-tabs__nav-next, .el-tabs__nav-prev{
+        line-height: 40px;
+        width: 40px;
+        display: inline-block;
+        text-align: center;
+    }
+
+
+}
+
+.el-tabs--card{
+    background-color: #fff
+}
+
+
+.tree{
+    .el-tree-node__content{
+        height:42px;
+        border-bottom:1px solid #f2f4f5;
+    }
+}

+ 243 - 242
src/main/vue/src/pages/Admin.vue

@@ -37,8 +37,7 @@
             <el-aside class="aside">
             <el-aside class="aside">
 
 
                 <div class="userInfo" :style="{height:collapse?'100px':'220px'}">
                 <div class="userInfo" :style="{height:collapse?'100px':'220px'}">
-                    <img :style="{height:collapse?'30px':'70px',width:collapse?'30px':'70px'}"
-                         :src="userInfo ? userInfo.icon || '' : ''" class="avatar"/>
+                    <img :style="{height:collapse?'30px':'70px',width:collapse?'30px':'70px'}" :src="userInfo ? userInfo.icon || '' : ''" class="avatar" />
                     <div v-if="!collapse" class="name">{{userInfo.username}}</div>
                     <div v-if="!collapse" class="name">{{userInfo.username}}</div>
                     <div v-if="!collapse" class="workNumber">{{userInfo.workNumber}}</div>
                     <div v-if="!collapse" class="workNumber">{{userInfo.workNumber}}</div>
                 </div>
                 </div>
@@ -51,14 +50,12 @@
             </el-aside>
             </el-aside>
             <el-container>
             <el-container>
                 <el-header height='40px' style='padding:0'>
                 <el-header height='40px' style='padding:0'>
-                    <el-tabs class="head-tabs" height='40px' v-model="editableTabsValue2" type="card" closable
-                             @tab-remove="removeTab" @tab-click="chooseOne">
-                        <el-tab-pane v-for="(item, index) in loginHistory" :key="item.name" :label="item.title"
-                                     :name="item.name">
+                    <el-tabs class="head-tabs" height='40px' v-model="editableTabsValue2" type="card" closable @tab-remove="removeTab" @tab-click="chooseOne">
+                        <el-tab-pane v-for="(item, index) in loginHistory" :key="item.name" :label="item.title" :name="item.name">
                         </el-tab-pane>
                         </el-tab-pane>
                     </el-tabs>
                     </el-tabs>
                 </el-header>
                 </el-header>
-                <el-main>
+                <el-main class="main">
                     <router-view></router-view>
                     <router-view></router-view>
                 </el-main>
                 </el-main>
             </el-container>
             </el-container>
@@ -68,286 +65,290 @@
 </template>
 </template>
 
 
 <script>
 <script>
-    import SysMenu from '../components/SysMenu'
-    import NavMenu from '../components/NavMenu'
-    import {mapState} from 'vuex'
+import SysMenu from '../components/SysMenu'
+import NavMenu from '../components/NavMenu'
+import { mapState } from 'vuex'
 
 
-    export default {
-        name: 'App',
-        mounted() {
-            this.getMenus();
-            let fn = () => {
-                this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+export default {
+    name: 'App',
+    mounted() {
+        this.getMenus();
+        let fn = () => {
+            this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
 
 
-            };
-            document.addEventListener('fullscreenchange', fn);
-            document.addEventListener('webkitfullscreenchange', fn);
-            document.addEventListener('mozfullscreenchange', fn);
-            document.addEventListener('MSFullscreenChange', fn);
-        },
-        data() {
-            return {
-                rawMenus: [],
-                menus: [],
-                activeMenu: '',
-                menuPath: [],
-                collapse: false,
-                isFullscreen: false,
-                editableTabsValue2: '/dashboard',
-                flag: true
-            }
-        },
-        computed: {
-            ...mapState(['userInfo', 'loginHistory', 'chooseLogin'])
-        },
-        methods: {
-            findActiveMenu() {
-                var list = [...this.loginHistory]
-                this.activeMenu = '';
-                this.menuPath = [];
-                let path = this.$route.path;
-                const findActiveMenu = (parents, childMenus) => {
-                    childMenus.forEach(i => {
-                        let parents_copy = [...parents];
-                        if (i.href === path) {
-                            parents_copy.push(i);
-                            this.menuPath = parents_copy.map(i => i.name);
-                            this.activeMenu = i.id;
-                            if (this.flag) {
-                                var flag = false
-                                list.forEach(item => {
-                                    if (item.name == i.href) {
-                                        flag = true
-                                    }
-                                })
-                                if (!flag) {
-                                    list.push({
-                                        name: i.href,
-                                        title: i.name
-                                    })
-                                    this.$store.commit('updateLoginHistory', list)
-                                    this.editableTabsValue2 = i.href
+        };
+        document.addEventListener('fullscreenchange', fn);
+        document.addEventListener('webkitfullscreenchange', fn);
+        document.addEventListener('mozfullscreenchange', fn);
+        document.addEventListener('MSFullscreenChange', fn);
+    },
+    data() {
+        return {
+            rawMenus: [],
+            menus: [],
+            activeMenu: '',
+            menuPath: [],
+            collapse: false,
+            isFullscreen: false,
+            editableTabsValue2: '/dashboard',
+            flag: true
+        }
+    },
+    computed: {
+        ...mapState(['userInfo', 'loginHistory', 'chooseLogin'])
+    },
+    methods: {
+        findActiveMenu() {
+            var list = [...this.loginHistory]
+            this.activeMenu = '';
+            this.menuPath = [];
+            let path = this.$route.path;
+            const findActiveMenu = (parents, childMenus) => {
+                childMenus.forEach(i => {
+                    let parents_copy = [...parents];
+                    if (i.href === path) {
+                        parents_copy.push(i);
+                        this.menuPath = parents_copy.map(i => i.name);
+                        this.activeMenu = i.id;
+                        if (this.flag) {
+                            var flag = false
+                            list.forEach(item => {
+                                if (item.name == i.href) {
+                                    flag = true
                                 }
                                 }
-
+                            })
+                            if (!flag) {
+                                list.push({
+                                    name: i.href,
+                                    title: i.name
+                                })
+                                this.$store.commit('updateLoginHistory', list)
+                                this.editableTabsValue2 = i.href
                             }
                             }
 
 
+                        }
 
 
-                        } else {
-                            if (i.children) {
-                                parents_copy.push(i);
-                                findActiveMenu(parents_copy, i.children);
-                            }
+
+                    } else {
+                        if (i.children) {
+                            parents_copy.push(i);
+                            findActiveMenu(parents_copy, i.children);
                         }
                         }
-                    })
-                };
-                findActiveMenu([], this.rawMenus);
-            },
-            getMenus() {
-                this.$http.get({
-                    url: '/sysMenu/userMenuTree',
-                    data: {
-                        userId: this.userInfo.id
-                    }
-                }).then(res => {
-                    if (res.success) {
-                        this.rawMenus = res.data;
-                        this.menus = res.data;
-                        this.findActiveMenu();
                     }
                     }
                 })
                 })
-            },
-            toggleFullScreen() {
-                this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
-                let element = document.body;
-                let requestMethod;
-                if (this.isFullscreen) {
-                    requestMethod = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen;
-                } else {
-                    requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
-                }
-                if (requestMethod) {
-                    requestMethod.call(this.isFullscreen ? document : element);
+            };
+            findActiveMenu([], this.rawMenus);
+        },
+        getMenus() {
+            this.$http.get({
+                url: '/sysMenu/userMenuTree',
+                data: {
+                    userId: this.userInfo.id
                 }
                 }
-            },
-            onCommand(command) {
-                if (command === 'logout') {
-                    this.$http.post({
-                        url: '/auth/logout'
-                    }).then(res => {
-                        if (res.success) {
-                            this.$store.commit('updateUserInfo', null);
-                            this.$router.replace('/login');
-                        }
-                    })
+            }).then(res => {
+                if (res.success) {
+                    this.rawMenus = res.data;
+                    this.menus = res.data;
+                    this.findActiveMenu();
                 }
                 }
-            },
-            removeTab(temp) {
-                console.log(temp)
-                var list = [...this.loginHistory]
-
-                list.forEach((item, index) => {
-                    if (item.name == temp) {
-                        list.splice(index, 1)
+            })
+        },
+        toggleFullScreen() {
+            this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+            let element = document.body;
+            let requestMethod;
+            if (this.isFullscreen) {
+                requestMethod = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen;
+            } else {
+                requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
+            }
+            if (requestMethod) {
+                requestMethod.call(this.isFullscreen ? document : element);
+            }
+        },
+        onCommand(command) {
+            if (command === 'logout') {
+                this.$http.post({
+                    url: '/auth/logout'
+                }).then(res => {
+                    if (res.success) {
+                        this.$store.commit('updateUserInfo', null);
+                        this.$router.replace('/login');
                     }
                     }
                 })
                 })
+            }
+        },
+        removeTab(temp) {
+            console.log(temp)
+            var list = [...this.loginHistory]
 
 
-                if (list.length == 0) {
-                    list.push({
-                        name: '/dashboard',
-                        title: '首页'
-                    })
+            list.forEach((item, index) => {
+                if (item.name == temp) {
+                    list.splice(index, 1)
                 }
                 }
+            })
 
 
+            if (list.length == 0) {
+                list.push({
+                    name: '/dashboard',
+                    title: '首页'
+                })
+            }
 
 
-                this.$store.commit('updateLoginHistory', list)
-                setTimeout(() => {
-                    if (temp == this.editableTabsValue2) {
 
 
-                        this.$router.push({
-                            path: list[0].name
-                        })
-                        this.$store.commit('updateChooseLogin', list[0].name)
+            this.$store.commit('updateLoginHistory', list)
+            setTimeout(() => {
+                if (temp == this.editableTabsValue2) {
 
 
-                    }
+                    this.$router.push({
+                        path: list[0].name
+                    })
+                    this.$store.commit('updateChooseLogin', list[0].name)
 
 
-                }, 100);
-            },
-            chooseOne(item) {
-                this.$router.push({
-                    path: item.name
-                })
-                this.editableTabsValue2 = item.name
-            }
-        },
-        watch: {
-            $route(val) {
-                this.findActiveMenu(this.rawMenus);
-                this.flag = false
-            },
-            isFullscreen(val) {
-                this.$refs.fullscreen.innerHTML = '';
-                let i = document.createElement('i');
-                i.style.fontSize = '20px';
-                i.className = val ? 'fas fa-compress' : 'fas fa-expand';
-                this.$refs.fullscreen.append(i);
-                FontAwesome.dom.i2svg();
-            },
-            chooseLogin() {
-                if (this.chooseLogin) {
-                    this.editableTabsValue2 = this.chooseLogin
                 }
                 }
-            }
+
+            }, 100);
+        },
+        chooseOne(item) {
+            this.$router.push({
+                path: item.name
+            })
+            this.editableTabsValue2 = item.name
+        }
+    },
+    watch: {
+        $route(val) {
+            this.findActiveMenu(this.rawMenus);
+            this.flag = false
+        },
+        isFullscreen(val) {
+            this.$refs.fullscreen.innerHTML = '';
+            let i = document.createElement('i');
+            i.style.fontSize = '20px';
+            i.className = val ? 'fas fa-compress' : 'fas fa-expand';
+            this.$refs.fullscreen.append(i);
+            FontAwesome.dom.i2svg();
         },
         },
-        components: {
-            SysMenu,
-            NavMenu
+        chooseLogin() {
+            if (this.chooseLogin) {
+                this.editableTabsValue2 = this.chooseLogin
+            }
         }
         }
+    },
+    components: {
+        SysMenu,
+        NavMenu
     }
     }
+}
 </script>
 </script>
 <style lang="less">
 <style lang="less">
-    .aside {
-        width: auto !important;
-        .el-menu {
-            border: none !important;
-            &:not(.el-menu--collapse) {
-                width: 200px;
-            }
+.aside {
+    width: auto !important;
+    .el-menu {
+        border: none !important;
+        &:not(.el-menu--collapse) {
+            width: 200px;
         }
         }
     }
     }
+}
 </style>
 </style>
 <style lang="less" scoped>
 <style lang="less" scoped>
-    #app {
-        height: 100%;
-    }
+#app {
+    height: 100%;
+}
 
 
-    .header {
-        color: #fff;
-        background-color: #409EFF;
+.header {
+    color: #fff;
+    background-color: #409eff;
+    display: flex;
+    align-items: center;
+    padding-left: 0;
+    // border-bottom: 1px solid #dcdfe6;
+    height: 68px;
+
+    .logo-wrapper {
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
-        padding-left: 0;
-        // border-bottom: 1px solid #dcdfe6;
-        height: 68px;
-
-        .logo-wrapper {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            color: white;
-            font-size: 20px;
-            font-weight: 700;
-            // background: fade(black, 20%);
-            padding-left: 15px;
-            img {
-                height: 36px;
-            }
+        justify-content: center;
+        color: white;
+        font-size: 20px;
+        font-weight: 700;
+        // background: fade(black, 20%);
+        padding-left: 15px;
+        img {
+            height: 36px;
         }
         }
+    }
 
 
-        .header-btn {
-            width: 60px;
-            height: 68px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            cursor: pointer;
+    .header-btn {
+        width: 60px;
+        height: 68px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+        transition: all 0.3s;
+        & > div {
             transition: all 0.3s;
             transition: all 0.3s;
-            & > div {
-                transition: all 0.3s;
-            }
-            &:hover {
-                background: fade(black, 10%);
-            }
         }
         }
-        .avatar {
-            width: 40px;
-            height: 40px;
-            border: 1px solid #ebebeb;
-            border-radius: 50%;
+        &:hover {
+            background: fade(black, 10%);
         }
         }
-        a {
-            &:visited {
-                color: #fff;
-                font-weight: bold;
-            }
+    }
+    .avatar {
+        width: 40px;
+        height: 40px;
+        border: 1px solid #ebebeb;
+        border-radius: 50%;
+    }
+    a {
+        &:visited {
+            color: #fff;
+            font-weight: bold;
         }
         }
     }
     }
+}
 
 
-    .aside {
-        background: #232e3b;
-        transition: all 0.4s ease;
-        -ms-overflow-style: none;
+.aside {
+    background: #232e3b;
+    transition: all 0.4s ease;
+    -ms-overflow-style: none;
 
 
-        .userInfo {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            flex-direction: column;
-            height: 220px;
-            img {
-                width: 70px;
-                height: 70px;
-                border-radius: 100%;
-                margin-top: 20px;
-            }
+    .userInfo {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-direction: column;
+        height: 220px;
+        img {
+            width: 70px;
+            height: 70px;
+            border-radius: 100%;
+            margin-top: 20px;
+        }
 
 
-            .name {
-                font-size: 20px;
-                font-weight: 500;
-                color: rgba(255, 255, 255, 1);
-                line-height: 28px;
-                margin-top: 12px;
-            }
+        .name {
+            font-size: 20px;
+            font-weight: 500;
+            color: rgba(255, 255, 255, 1);
+            line-height: 28px;
+            margin-top: 12px;
+        }
 
 
-            .workNumber {
-                font-size: 14px;
-                font-weight: 400;
-                color: rgba(255, 255, 255, 1);
-                line-height: 20px;
-            }
+        .workNumber {
+            font-size: 14px;
+            font-weight: 400;
+            color: rgba(255, 255, 255, 1);
+            line-height: 20px;
         }
         }
     }
     }
+}
 
 
-    .aside::-webkit-scrollbar {
-        display: none;
-    }
+.aside::-webkit-scrollbar {
+    display: none;
+}
+
+.main {
+    background-color: #f2f4f5;
+}
 </style>
 </style>

+ 315 - 235
src/main/vue/src/pages/Departs.vue

@@ -1,273 +1,353 @@
 <template>
 <template>
-    <el-container class="container">
+    <div class="container">
+        <div class="topTree" :style="{height:(allHeight-142)+'px'}">
+            <div @mouseleave="showTable=false" style="position:relactive">
+                <el-tree :data="menus" class="tree" :render-content="renderContent" :highlight-current="true" :expand-on-click-node="false" @node-click="nodeClick" node-key="id" default-expand-all>
+                </el-tree>
+
+                <div class="tipRight" id='tipRight' v-if="showTable" :style="{top:tableTop+'px'}">
+                    <el-table :data="departUsers" :show-header="false">
+                        <el-table-column prop="username" label="用户名"></el-table-column>
+                    </el-table>
+                    <div class="popper__arrow"></div>
+                </div>
+            </div>
+
+        </div>
+
+        <!-- <el-button size="mini" type="text" @click="addRootMenu" class="btn-add">添加</el-button> -->
+        <el-button type="primary" @click="addRootMenu" style="margin-left: 24px;margin-top:20px;width:98px;">添加</el-button>
+
+        <el-dialog :visible.sync="dialogVisible" title="添加菜单">
+            <el-form :model="menu" ref="form" size="small">
+                <el-form-item label="部门名称" prop="departName" :rules="[{required: true, message: '请填写部门名', trigger: 'blur'}]">
+                    <el-input v-model="menu.departName"></el-input>
+                </el-form-item>
+                <el-form-item label="部门代码" prop="departCode">
+                    <el-input v-model="menu.departCode"></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer">
+                <el-button @click="dialogVisible = false" size="small">取消</el-button>
+                <el-button type="primary" @click="addMenu" :loading="loading" size="small">保存</el-button>
+            </div>
+        </el-dialog>
+    </div>
+    <!-- <el-container class="container">
         <el-aside class="depart-tree" style="width: 400px;">
         <el-aside class="depart-tree" style="width: 400px;">
-            <el-tree
-                :data="menus"
-                :render-content="renderContent"
-                :highlight-current="true"
-                :expand-on-click-node="false"
-                @node-click="nodeClick"
-                node-key="id"
-                default-expand-all>
-            </el-tree>
-            <el-button size="mini" type="text" @click="addRootMenu" class="btn-add">添加</el-button>
+
         </el-aside>
         </el-aside>
         <el-main class="users">
         <el-main class="users">
-            <el-table :data="departUsers" :show-header="false">
-                <el-table-column prop="username" label="用户名"></el-table-column>
-            </el-table>
-            <el-dialog :visible.sync="dialogVisible" title="添加菜单">
-                <el-form :model="menu" ref="form" size="small">
-                    <el-form-item label="部门名称" prop="departName"
-                                  :rules="[{required: true, message: '请填写部门名', trigger: 'blur'}]">
-                        <el-input v-model="menu.departName"></el-input>
-                    </el-form-item>
-                    <el-form-item label="部门代码" prop="departCode">
-                        <el-input v-model="menu.departCode"></el-input>
-                    </el-form-item>
-                </el-form>
-                <div slot="footer">
-                    <el-button @click="dialogVisible = false" size="small">取消</el-button>
-                    <el-button type="primary" @click="addMenu" :loading="loading" size="small">保存</el-button>
-                </div>
-            </el-dialog>
+
         </el-main>
         </el-main>
-    </el-container>
+    </el-container> -->
 </template>
 </template>
 <script>
 <script>
-    import axios from 'axios'
+import axios from 'axios'
+import { mapState } from 'vuex'
 
 
-    export default {
-        created() {
-            this.getData();
+export default {
+    created() {
+        this.getData();
+    },
+    data() {
+        return {
+            dialogVisible: false,
+            curr: null,
+            loading: false,
+            menus: [],
+            menu: {
+                departName: '',
+                departCode: ''
+            },
+            departUsers: [],
+            showTable: false,
+            tableTop: 0,
+        }
+    },
+    computed: {
+        ...mapState(['allHeight']),
+    },
+    methods: {
+        addRootMenu() {
+            this.menu = {
+                parentId: 0,
+                departName: '',
+                departCode: ''
+            };
+            /*  if (this.menus && this.menus.length > 0) {
+                  this.menu.sort = this.menus[this.menus.length - 1].extra.sort + 1;
+              } else {
+                  this.menu.sort = 1;
+              }*/
+            this.dialogVisible = true;
         },
         },
-        data() {
-            return {
-                dialogVisible: false,
-                curr: null,
-                loading: false,
-                menus: [],
-                menu: {
-                    departName: '',
-                    departCode: ''
-                },
-                departUsers: []
+        showAddDialog(node, data) {
+            this.menu = {
+                parentId: node.data.extra.id,
+                departName: '',
+                departCode: ''
+            };
+            if (node.childNodes && node.childNodes.length > 0) {
+                this.menu.sort = node.childNodes[node.childNodes.length - 1].data.extra.sort + 1;
+            } else {
+                this.menu.sort = 1;
             }
             }
+            this.dialogVisible = true;
         },
         },
-        methods: {
-            addRootMenu() {
-                this.menu = {
-                    parentId: 0,
-                    departName: '',
-                    departCode: ''
-                };
-                /*  if (this.menus && this.menus.length > 0) {
-                      this.menu.sort = this.menus[this.menus.length - 1].extra.sort + 1;
-                  } else {
-                      this.menu.sort = 1;
-                  }*/
-                this.dialogVisible = true;
-            },
-            showAddDialog(node, data) {
-                this.menu = {
-                    parentId: node.data.extra.id,
-                    departName: '',
-                    departCode: ''
-                };
-                if (node.childNodes && node.childNodes.length > 0) {
-                    this.menu.sort = node.childNodes[node.childNodes.length - 1].data.extra.sort + 1;
-                } else {
-                    this.menu.sort = 1;
-                }
-                this.dialogVisible = true;
-            },
-            addMenu() {
-                this.$refs.form.validate(valid => {
-                    if (valid) {
-                        this.loading = true;
-                        this.$http.post({
-                            url: this.menu.id ? '/departInfo/update' : '/departInfo/save',
-                            data: this.menu
-                        }).then(res => {
-                            this.loading = false;
-                            if (res.success) {
-                                this.$message.success('保存成功');
-                                this.dialogVisible = false;
-                                this.getData();
-                            } else {
-                                this.$message.warning('添加失败')
-                            }
-                        })
-                    }
-                });
-            },
-            showEditDialog(node, data) {
-                this.menu = {
-                    id: data.extra.id,
-                    departName: data.extra.departName,
-                    departCode: data.extra.departCode,
-                };
-                this.dialogVisible = true;
-            },
-            moveUp(node, data) {
-                const formData = d => {
-                    let formData = new FormData();
-                    for (let key in d) {
-                        if (d.hasOwnProperty(key)) {
-                            formData.append(key, d[key]);
-                        }
-                    }
-                    return formData;
-                };
-                if (node.previousSibling) {
-                    axios.all([axios.post(this.$baseUrl + '/departInfo/update', formData({
-                        id: node.data.id,
-                        sort: node.previousSibling.data.extra.sort
-                    })), axios.post(this.$baseUrl + '/departInfo/update', formData({
-                        id: node.previousSibling.data.id,
-                        sort: node.data.extra.sort
-                    }))]).then(axios.spread((acct, perms) => {
-                        this.getData();
-                    }));
-                }
-            },
-            moveDown(node, data) {
-                const formData = d => {
-                    let formData = new FormData();
-                    for (let key in d) {
-                        if (d.hasOwnProperty(key)) {
-                            formData.append(key, d[key]);
-                        }
-                    }
-                    return formData;
-                };
-                if (node.nextSibling) {
-                    axios.all([axios.post(this.$baseUrl + '/departInfo/update', formData({
-                        id: node.data.id,
-                        sort: node.nextSibling.data.extra.sort
-                    })), axios.post(this.$baseUrl + '/departInfo/update', formData({
-                        id: node.nextSibling.data.id,
-                        sort: node.data.extra.sort
-                    }))]).then(axios.spread((acct, perms) => {
-                        this.getData();
-                    }));
-                }
-            },
-            remove(node, data) {
-                this.$confirm('确定删除菜单?', '提示', {
-                    confirmButtonText: '确定',
-                    cancelButtonText: '取消',
-                    type: 'error'
-                }).then(() => {
+        addMenu() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.loading = true;
                     this.$http.post({
                     this.$http.post({
-                        url: '/departInfo/del',
-                        data: {
-                            id: data.id
-                        }
+                        url: this.menu.id ? '/departInfo/update' : '/departInfo/save',
+                        data: this.menu
                     }).then(res => {
                     }).then(res => {
+                        this.loading = false;
                         if (res.success) {
                         if (res.success) {
-                            this.$message.success('删除成功');
+                            this.$message.success('保存成功');
+                            this.dialogVisible = false;
                             this.getData();
                             this.getData();
                         } else {
                         } else {
-                            this.$message.error('删除失败');
+                            this.$message.warning('添加失败')
                         }
                         }
                     })
                     })
-                }).catch(() => {
-                });
-            },
-            nodeClick(data, node, component) {
-                this.$http.get({
-                    url: '/departInfo/departUsers',
-                    data: {
-                        departId: data.id
+                }
+            });
+        },
+        showEditDialog(node, data) {
+            this.menu = {
+                id: data.extra.id,
+                departName: data.extra.departName,
+                departCode: data.extra.departCode,
+            };
+            this.dialogVisible = true;
+        },
+        moveUp(node, data) {
+            const formData = d => {
+                let formData = new FormData();
+                for (let key in d) {
+                    if (d.hasOwnProperty(key)) {
+                        formData.append(key, d[key]);
                     }
                     }
-                }).then(res => {
-                    if (res.success) {
-                        this.departUsers = res.data
+                }
+                return formData;
+            };
+            if (node.previousSibling) {
+                axios.all([axios.post(this.$baseUrl + '/departInfo/update', formData({
+                    id: node.data.id,
+                    sort: node.previousSibling.data.extra.sort
+                })), axios.post(this.$baseUrl + '/departInfo/update', formData({
+                    id: node.previousSibling.data.id,
+                    sort: node.data.extra.sort
+                }))]).then(axios.spread((acct, perms) => {
+                    this.getData();
+                }));
+            }
+        },
+        moveDown(node, data) {
+
+            const formData = d => {
+                let formData = new FormData();
+                for (let key in d) {
+                    if (d.hasOwnProperty(key)) {
+                        formData.append(key, d[key]);
+                    }
+                }
+                return formData;
+            };
+            if (node.nextSibling) {
+                axios.all([axios.post(this.$baseUrl + '/departInfo/update', formData({
+                    id: node.data.id,
+                    sort: node.nextSibling.data.extra.sort
+                })), axios.post(this.$baseUrl + '/departInfo/update', formData({
+                    id: node.nextSibling.data.id,
+                    sort: node.data.extra.sort
+                }))]).then(axios.spread((acct, perms) => {
+                    this.getData();
+                }));
+            }
+        },
+        remove(node, data) {
+            this.$confirm('确定删除菜单?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'error'
+            }).then(() => {
+                this.$http.post({
+                    url: '/departInfo/del',
+                    data: {
+                        id: data.id
                     }
                     }
-                })
-            },
-            getData() {
-                this.$http.get({
-                    url: '/departInfo/departTree'
                 }).then(res => {
                 }).then(res => {
                     if (res.success) {
                     if (res.success) {
-                        const parse = (trees) => {
-                            trees.sort((a, b) => {
-                                return a.extra.sort - b.extra.sort;
-                            });
-                            return trees.map(i => {
-                                let t = {
-                                    id: i.id,
-                                    label: i.name,
-                                    parentId: i.parentId,
-                                    extra: i.extra
-                                };
-                                if (i.children instanceof Array) {
-                                    t.children = parse(i.children);
-                                }
-                                return t;
-                            });
-                        };
-                        this.menus = parse(res.data);
+                        this.$message.success('删除成功');
+                        this.getData();
+                    } else {
+                        this.$message.error('删除失败');
                     }
                     }
                 })
                 })
-            },
-            renderContent(h, { node, data, store }) {
-                return (
-                    <span class="custom-tree-node">
-                        <span>{node.label}</span>
-                        <span class="url">{data.extra.href}</span>
-                        <span class="opt">
-                            <el-button size="mini" type="text" on-click={ () => this.moveUp(node, data) } class="up">上移</el-button>
-                            <el-button size="mini" type="text" on-click={ () => this.moveDown(node, data) }>下移</el-button>
-                            <el-button size="mini" type="text" on-click={ () => this.showEditDialog(node, data) }>编辑</el-button>
-                            <el-button size="mini" type="text" on-click={ () => this.showAddDialog(node, data) }>添加</el-button>
-                            <el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>删除</el-button>
-                        </span>
+            }).catch(() => {
+            });
+        },
+        nodeClick(data, node, component) {
+
+
+            this.$http.get({
+                url: '/departInfo/departUsers',
+                data: {
+                    departId: data.id
+                }
+            }).then(res => {
+                if (res.success) {
+                    this.departUsers = res.data
+                    var list = document.getElementsByClassName('el-tree-node__content')
+                    this.tableTop = list[this.getIndex(data.id)].offsetTop
+                    this.showTable = true
+                }
+            })
+
+
+        },
+        getIndex(id) {
+            var index = 0
+            var menus = [...this.menus]
+            var list = this.getList(menus, [])
+            list.forEach((item, i) => {
+                if (item == id) {
+                    index = i
+                }
+            })
+            return index
+        },
+        getList(menus, nowList) {
+            var list = nowList
+            menus.forEach(item => {
+                if (item.extra.id) {
+                    list.push(item.extra.id)
+                }
+                if (item.children) {
+                    item.children.forEach(todo => {
+                        list = this.getList([todo], list)
+                    })
+                }
+            })
+
+            return list
+        },
+        getData() {
+            this.$http.get({
+                url: '/departInfo/departTree'
+            }).then(res => {
+                if (res.success) {
+                    const parse = (trees) => {
+                        trees.sort((a, b) => {
+                            return a.extra.sort - b.extra.sort;
+                        });
+                        return trees.map(i => {
+                            let t = {
+                                id: i.id,
+                                label: i.name,
+                                parentId: i.parentId,
+                                extra: i.extra
+                            };
+                            if (i.children instanceof Array) {
+                                t.children = parse(i.children);
+                            }
+                            return t;
+                        });
+                    };
+                    this.menus = parse(res.data);
+                }
+            })
+        },
+        renderContent(h, { node, data, store }) {
+            return (
+                <span class="custom-tree-node">
+                    <span>{node.label}</span>
+                    <span class="url">{data.extra.href}</span>
+                    <span class="opt">
+                        <el-button size="mini" type="primary" plain on-click={() => this.moveUp(node, data)} class="up">上移</el-button>
+                        <el-button size="mini" type="primary" plain on-click={() => this.moveDown(node, data)}>下移</el-button>
+                        <el-button size="mini" type="warning" plain on-click={() => this.showEditDialog(node, data)}>编辑</el-button>
+                        <el-button size="mini" type="success" plain on-click={() => this.showAddDialog(node, data)}>添加</el-button>
+                        <el-button size="mini" type="danger" plain on-click={() => this.remove(node, data)}>删除</el-button>
                     </span>
                     </span>
-                );
-            }
+                </span>
+            );
         }
         }
     }
     }
+}
 </script>
 </script>
 <style lang="less">
 <style lang="less">
-    .container {
-        display: flex;
-        .depart-tree {
+.container {
+    padding: 20px;
+    background-color: #fff;
+    border-radius: 4px;
+
+    .topTree {
+        overflow: auto;
+        // padding-bottom: 20px;
+        border: 1px solid #f2f4f5;
+        position: relative;
+
+        .tipRight {
+            position: absolute;
+            top: 0;
+            left: 200px;
+            z-index: 500;
             width: 400px;
             width: 400px;
-        }
-        .btn-add {
-            margin-left: 20px;
-        }
-        .users{
-            flex-grow: 1;
+            padding: 12px;
+            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+            border-radius: 4px;
+            background-color: #fff;
+            // transform: translateY(-30%);
+            .popper__arrow {
+                background-color: #fff;
+                box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.1);
+                transform: rotate(125deg);
+                width: 10px;
+                height: 10px;
+                position: absolute;
+                left: -4px;
+                top: 15px;
+            }
         }
         }
     }
     }
+    // display: flex;
+    // .depart-tree {
+    //     width: 400px;
+    // }
+    // .btn-add {
+    //     margin-left: 20px;
+    // }
+    // .users{
+    //     flex-grow: 1;
+    // }
+}
 
 
-    .custom-tree-node {
-        flex: 1;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        font-size: 14px;
-        padding-right: 8px;
-        .url {
-            flex-grow: 1;
-            text-align: right;
-            margin-right: 20px;
-            color: #999;
-        }
-        .opt {
-            opacity: 0;
-        }
+.custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+    .url {
+        flex-grow: 1;
+        text-align: right;
+        margin-right: 20px;
+        color: #999;
     }
     }
-
-    .custom-tree-node:hover {
-        .opt {
-            opacity: 1;
-        }
+    .opt {
+        opacity: 0;
     }
     }
+}
 
 
+.custom-tree-node:hover {
+    .opt {
+        opacity: 1;
+    }
+}
 </style>
 </style>
 
 

+ 243 - 232
src/main/vue/src/pages/Menus.vue

@@ -1,15 +1,12 @@
 <!--suppress ALL -->
 <!--suppress ALL -->
 <template>
 <template>
-    <div style="">
-        <el-tree
-            :data="menus"
-            :render-content="renderContent"
-            :highlight-current="true"
-            :expand-on-click-node="true"
-            node-key="id"
-            default-expand-all>
-        </el-tree>
-        <el-button size="mini" type="text" @click="addRootMenu" style="margin-left: 24px">添加</el-button>
+    <div class="menuContainer">
+        <div class="topTree" :style="{height:(allHeight-142)+'px'}">
+            <el-tree class="tree" :data="menus" :render-content="renderContent" :highlight-current="true" :expand-on-click-node="true" node-key="id" default-expand-all>
+            </el-tree>
+        </div>
+
+        <el-button  type="primary" @click="addRootMenu" style="margin-left: 24px;margin-top:20px;width:98px;">添加</el-button>
         <el-dialog :visible.sync="dialogVisible" title="添加菜单">
         <el-dialog :visible.sync="dialogVisible" title="添加菜单">
             <el-form :model="menu" ref="form" label-position="top" size="small">
             <el-form :model="menu" ref="form" label-position="top" size="small">
                 <el-form-item label="菜单名" prop="name" :rules="[{required: true, message: '请填写菜单名', trigger: 'blur'}]">
                 <el-form-item label="菜单名" prop="name" :rules="[{required: true, message: '请填写菜单名', trigger: 'blur'}]">
@@ -34,258 +31,272 @@
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
-    import axios from 'axios'
+import axios from 'axios'
+import { mapState } from 'vuex'
 
 
-    export default {
-        created() {
-            this.getData();
-        },
-        data() {
-            return {
-                dialogVisible: false,
-                curr: null,
-                loading: false,
-                menus: [],
-                menu: {
-                    name: '',
-                    href: '',
-                    icon: ''
-                },
+export default {
+    created() {
+        this.getData();
+    },
+    data() {
+        return {
+            dialogVisible: false,
+            curr: null,
+            loading: false,
+            menus: [],
+            menu: {
+                name: '',
+                href: '',
                 icon: ''
                 icon: ''
+            },
+            icon: ''
+        }
+    },
+    computed: {
+        ...mapState(['allHeight']),
+    },
+    methods: {
+        addRootMenu() {
+            this.menu = {
+                parentId: 0,
+                name: '',
+                href: '',
+                icon: 'bars'
+            };
+            this.icon = 'bars';
+            if (this.menus && this.menus.length > 0) {
+                this.menu.sort = this.menus[this.menus.length - 1].sort + 1;
+            } else {
+                this.menu.sort = 1;
             }
             }
+            this.dialogVisible = true;
+            setTimeout(() => {
+                this.showIcon('bars');
+            }, 100)
         },
         },
-        methods: {
-            addRootMenu() {
-                this.menu = {
-                    parentId: 0,
-                    name: '',
-                    href: '',
-                    icon: 'bars'
-                };
-                this.icon = 'bars';
-                if (this.menus && this.menus.length > 0) {
-                    this.menu.sort = this.menus[this.menus.length - 1].sort + 1;
-                } else {
-                    this.menu.sort = 1;
-                }
-                this.dialogVisible = true;
-                setTimeout(()=>{
-                    this.showIcon('bars');
-                }, 100)
-            },
-            showAddDialog(node, data) {
-                this.menu = {
-                    parentId: node.data.id,
-                    name: '',
-                    href: '',
-                    icon: null
-                };
-                this.icon = '';
-                if (node.childNodes && node.childNodes.length > 0) {
-                    this.menu.sort = node.childNodes[node.childNodes.length - 1].data.sort + 1;
-                } else {
-                    this.menu.sort = 1;
-                }
-                this.dialogVisible = true;
-                setTimeout(() => {
-                    this.showIcon('');
-                }, 100)
-            },
-            showEditDialog(node, data) {
-                const getIconName = icon => {
-                    let iconName = '';
-                    if (icon) {
-                        iconName = icon.replace('fas ', '').replace('fab ', '').replace('fa-', '');
-                    }
-                    return iconName || null;
+        showAddDialog(node, data) {
+            this.menu = {
+                parentId: node.data.id,
+                name: '',
+                href: '',
+                icon: null
+            };
+            this.icon = '';
+            if (node.childNodes && node.childNodes.length > 0) {
+                this.menu.sort = node.childNodes[node.childNodes.length - 1].data.sort + 1;
+            } else {
+                this.menu.sort = 1;
+            }
+            this.dialogVisible = true;
+            setTimeout(() => {
+                this.showIcon('');
+            }, 100)
+        },
+        showEditDialog(node, data) {
+            const getIconName = icon => {
+                let iconName = '';
+                if (icon) {
+                    iconName = icon.replace('fas ', '').replace('fab ', '').replace('fa-', '');
                 }
                 }
-                let iconName = getIconName(data.icon);
-                this.menu = {
-                    id: data.id,
-                    name: data.name,
-                    href: data.href,
-                    icon: iconName
-                };
-                this.icon = iconName;
-                this.dialogVisible = true;
-                setTimeout(() => {
-                    this.showIcon(iconName);
-                }, 100)
-            },
-            addMenu() {
-                this.$refs.form.validate(valid => {
-                    if (valid) {
-                        this.loading = true;
-                        this.$http.post({
-                            url: this.menu.id ? '/sysMenu/update' : '/sysMenu/save',
-                            data: this.menu
-                        }).then(res => {
-                            this.loading = false;
-                            if (res.success) {
-                                this.$message.success('添加成功')
-                                this.dialogVisible = false;
-                                this.getData();
-                            } else {
-                                this.$message.warning('添加失败')
-                            }
-                        })
-                    }
-                });
-            },
-            remove(node, data) {
-                this.$confirm('确定删除菜单?', '提示', {
-                    confirmButtonText: '确定',
-                    cancelButtonText: '取消',
-                    type: 'error'
-                }).then(() => {
+                return iconName || null;
+            }
+            let iconName = getIconName(data.icon);
+            this.menu = {
+                id: data.id,
+                name: data.name,
+                href: data.href,
+                icon: iconName
+            };
+            this.icon = iconName;
+            this.dialogVisible = true;
+            setTimeout(() => {
+                this.showIcon(iconName);
+            }, 100)
+        },
+        addMenu() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.loading = true;
                     this.$http.post({
                     this.$http.post({
-                        url: '/sysMenu/del',
-                        data: {
-                            id: data.id
-                        }
+                        url: this.menu.id ? '/sysMenu/update' : '/sysMenu/save',
+                        data: this.menu
                     }).then(res => {
                     }).then(res => {
+                        this.loading = false;
                         if (res.success) {
                         if (res.success) {
-                            this.$message.success('删除成功');
+                            this.$message.success('添加成功')
+                            this.dialogVisible = false;
                             this.getData();
                             this.getData();
                         } else {
                         } else {
-                            this.$message.error('删除失败');
+                            this.$message.warning('添加失败')
                         }
                         }
                     })
                     })
-                }).catch(() => {
-                });
-            },
-            moveUp(node, data) {
-                const formData = d => {
-                    let formData = new FormData();
-                    for (let key in d) {
-                        if (d.hasOwnProperty(key)) {
-                            formData.append(key, d[key]);
-                        }
-                    }
-                    return formData;
                 }
                 }
-                if (node.previousSibling) {
-                    axios.all([axios.post(this.$baseUrl + '/sysMenu/update', formData({
-                        id: node.data.id,
-                        sort: node.previousSibling.data.sort
-                    })), axios.post(this.$baseUrl + '/sysMenu/update', formData({
-                        id: node.previousSibling.data.id,
-                        sort: node.data.sort
-                    }))]).then(axios.spread((acct, perms) => {
-                        this.getData();
-                    }));
-                }
-            },
-            moveDown(node, data) {
-                const formData = d => {
-                    let formData = new FormData();
-                    for (let key in d) {
-                        if (d.hasOwnProperty(key)) {
-                            formData.append(key, d[key]);
-                        }
+            });
+        },
+        remove(node, data) {
+            this.$confirm('确定删除菜单?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'error'
+            }).then(() => {
+                this.$http.post({
+                    url: '/sysMenu/del',
+                    data: {
+                        id: data.id
                     }
                     }
-                    return formData;
-                }
-                if (node.nextSibling) {
-                    axios.all([axios.post(this.$baseUrl + '/sysMenu/update', formData({
-                        id: node.data.id,
-                        sort: node.nextSibling.data.sort
-                    })), axios.post(this.$baseUrl + '/sysMenu/update', formData({
-                        id: node.nextSibling.data.id,
-                        sort: node.data.sort
-                    }))]).then(axios.spread((acct, perms) => {
-                        this.getData();
-                    }));
-                }
-            },
-            getData() {
-                this.$http.get({
-                    url: '/sysMenu/menuTree'
                 }).then(res => {
                 }).then(res => {
                     if (res.success) {
                     if (res.success) {
-                        this.menus = res.data
+                        this.$message.success('删除成功');
+                        this.getData();
+                    } else {
+                        this.$message.error('删除失败');
                     }
                     }
                 })
                 })
-            },
-            renderContent(h, {node, data, store}) {
-                return (
-                    <span class="custom-tree-node">
-                        <span>{data.name}</span>
-                        <span class="url">{data.href}</span>
-                        <span class="opt">
-                            <el-button size="mini" type="text" on-click={ (e) => {this.moveUp(node, data), e.stopPropagation()} } class="up">上移</el-button>
-                            <el-button size="mini" type="text" on-click={ (e) => {this.moveDown(node, data), e.stopPropagation()} }>下移</el-button>
-                            <el-button size="mini" type="text" on-click={ (e) => {this.showEditDialog(node, data), e.stopPropagation()} }>编辑</el-button>
-                            <el-button size="mini" type="text" on-click={ (e) => {this.showAddDialog(node, data), e.stopPropagation()} }>添加</el-button>
-                            <el-button size="mini" type="text" on-click={ (e) => {this.remove(node, data), e.stopPropagation()} }>删除</el-button>
-                        </span>
-                    </span>
-                );
-            },
-            showIcon(val) {
-                if (!this.$refs.iconContainer) return;
-                if (FontAwesome.icon({prefix: 'fas', iconName: val})) {
-                    this.$refs.iconContainer.innerHTML = '';
-                    let i = document.createElement('i');
-                    i.className = 'fas fa-' + val;
-                    this.$refs.iconContainer.append(i);
-                    FontAwesome.dom.i2svg();
-                    this.menu.icon = 'fas fa-' + val;
-                } else if (FontAwesome.icon({prefix: 'fab', iconName: val})) {
-                    this.$refs.iconContainer.innerHTML = '';
-                    let i = document.createElement('i');
-                    i.className = 'fab fa-' + val;
-                    this.$refs.iconContainer.append(i);
-                    FontAwesome.dom.i2svg();
-                    this.menu.icon = 'fab fa-' + val;
-                } else {
-                    this.$refs.iconContainer.innerHTML = '';
-                    let i = document.createElement('i');
-                    i.className = 'fab fa-' + val;
-                    this.$refs.iconContainer.append(i);
-                    FontAwesome.dom.i2svg();
-                    this.menu.icon = '';
+            }).catch(() => {
+            });
+        },
+        moveUp(node, data) {
+            const formData = d => {
+                let formData = new FormData();
+                for (let key in d) {
+                    if (d.hasOwnProperty(key)) {
+                        formData.append(key, d[key]);
+                    }
                 }
                 }
+                return formData;
+            }
+            if (node.previousSibling) {
+                axios.all([axios.post(this.$baseUrl + '/sysMenu/update', formData({
+                    id: node.data.id,
+                    sort: node.previousSibling.data.sort
+                })), axios.post(this.$baseUrl + '/sysMenu/update', formData({
+                    id: node.previousSibling.data.id,
+                    sort: node.data.sort
+                }))]).then(axios.spread((acct, perms) => {
+                    this.getData();
+                }));
             }
             }
         },
         },
-        watch: {
-            icon(val) {
-                this.showIcon(val);
+        moveDown(node, data) {
+            const formData = d => {
+                let formData = new FormData();
+                for (let key in d) {
+                    if (d.hasOwnProperty(key)) {
+                        formData.append(key, d[key]);
+                    }
+                }
+                return formData;
+            }
+            if (node.nextSibling) {
+                axios.all([axios.post(this.$baseUrl + '/sysMenu/update', formData({
+                    id: node.data.id,
+                    sort: node.nextSibling.data.sort
+                })), axios.post(this.$baseUrl + '/sysMenu/update', formData({
+                    id: node.nextSibling.data.id,
+                    sort: node.data.sort
+                }))]).then(axios.spread((acct, perms) => {
+                    this.getData();
+                }));
+            }
+        },
+        getData() {
+            this.$http.get({
+                url: '/sysMenu/menuTree'
+            }).then(res => {
+                if (res.success) {
+                    this.menus = res.data
+                }
+            })
+        },
+        renderContent(h, { node, data, store }) {
+            return (
+                <span class="custom-tree-node">
+                    <span>{data.name}</span>
+                    <span class="url">{data.href}</span>
+                    <span class="opt">
+                        <el-button size="mini" type="primary" plain  on-click={(e) => { this.moveUp(node, data), e.stopPropagation() }} class="up">上移</el-button>
+                        <el-button size="mini" type="primary" plain on-click={(e) => { this.moveDown(node, data), e.stopPropagation() }}>下移</el-button>
+                        <el-button size="mini" type="warning" plain on-click={(e) => { this.showEditDialog(node, data), e.stopPropagation() }}>编辑</el-button>
+                        <el-button size="mini" type="success" plain on-click={(e) => { this.showAddDialog(node, data), e.stopPropagation() }}>添加</el-button>
+                        <el-button size="mini" type="danger" plain on-click={(e) => { this.remove(node, data), e.stopPropagation() }}>删除</el-button>
+                    </span>
+                </span>
+            );
+        },
+        showIcon(val) {
+            if (!this.$refs.iconContainer) return;
+            if (FontAwesome.icon({ prefix: 'fas', iconName: val })) {
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fas fa-' + val;
+                this.$refs.iconContainer.append(i);
+                FontAwesome.dom.i2svg();
+                this.menu.icon = 'fas fa-' + val;
+            } else if (FontAwesome.icon({ prefix: 'fab', iconName: val })) {
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fab fa-' + val;
+                this.$refs.iconContainer.append(i);
+                FontAwesome.dom.i2svg();
+                this.menu.icon = 'fab fa-' + val;
+            } else {
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fab fa-' + val;
+                this.$refs.iconContainer.append(i);
+                FontAwesome.dom.i2svg();
+                this.menu.icon = '';
             }
             }
         }
         }
+    },
+    watch: {
+        icon(val) {
+            this.showIcon(val);
+        }
     }
     }
+}
 </script>
 </script>
 <style lang="less">
 <style lang="less">
-    .custom-tree-node {
-        flex: 1;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        font-size: 14px;
-        padding-right: 8px;
-        .url {
-            flex-grow: 1;
-            text-align: right;
-            margin-right: 20px;
-            color: #999;
-        }
-        .opt {
-            opacity: 0;
-        }
+.menuContainer {
+    background-color: #fff;
+    padding: 20px;
+    border-radius:4px;
+}
+.topTree {
+    overflow: auto;
+    // padding-bottom: 20px;
+    border:1px solid #F2F4F5;
+}
+.custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+    .url {
+        flex-grow: 1;
+        text-align: right;
+        margin-right: 20px;
+        color: #999;
     }
     }
+    .opt {
+        opacity: 0;
+    }
+}
 
 
-    .custom-tree-node:hover {
-        .opt {
-            opacity: 1;
-        }
+.custom-tree-node:hover {
+    .opt {
+        opacity: 1;
     }
     }
+}
 
 
-    .available-icons {
-        color: #409EFF;
+.available-icons {
+    color: #409eff;
+    text-decoration: none;
+    &:hover {
+        color: #409eff;
         text-decoration: none;
         text-decoration: none;
-        &:hover {
-            color: #409EFF;
-            text-decoration: none;
-        }
     }
     }
+}
 </style>
 </style>

+ 5 - 1
src/main/vue/src/vuex/index.js

@@ -6,6 +6,7 @@ Vue.use(Vuex);
 export default new Vuex.Store({
 export default new Vuex.Store({
     state: {
     state: {
         tableHeight: 0,
         tableHeight: 0,
+        allHeight: 0,
         fetchingData: false,
         fetchingData: false,
         userInfo: null,
         userInfo: null,
         farmName: '金山',
         farmName: '金山',
@@ -23,6 +24,9 @@ export default new Vuex.Store({
         updateTableHeight(state, height) {
         updateTableHeight(state, height) {
             state.tableHeight = height;
             state.tableHeight = height;
         },
         },
+        updateAllHeight(state, height) {
+            state.allHeight = height;
+        },
         updateFetchingData(state, fetchingData) {
         updateFetchingData(state, fetchingData) {
             state.fetchingData = fetchingData
             state.fetchingData = fetchingData
         },
         },
@@ -40,4 +44,4 @@ export default new Vuex.Store({
         }
         }
     },
     },
     actions: {}
     actions: {}
-});
+});

+ 1 - 1
src/main/webapp/WEB-INF/html/admin.html

@@ -1 +1 @@
-<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>管理后台</title><link rel=icon href=/static/favicon.ico><script src=/static/polyfill.min.js></script><script src=/static/fontawesome-v5.2.0.js></script><link href=/static/css/admin.2d4c802a4751c2f0bde6a42cf43a390d.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.b41429e29962885c75e6.js></script><script type=text/javascript src=/static/js/vendor.976c0ffa3464c7b2676f.js></script><script type=text/javascript src=/static/js/admin.f47d0062b4c2ab66e1cb.js></script></body></html>
+<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>管理后台</title><link rel=icon href=/static/favicon.ico><script src=/static/polyfill.min.js></script><script src=/static/fontawesome-v5.2.0.js></script><link href=/static/css/admin.1f7d6cc8efdc691d6129256abb8280da.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.351f207aa1b17a5fb955.js></script><script type=text/javascript src=/static/js/vendor.ff9d3ee4e85e6faf30a3.js></script><script type=text/javascript src=/static/js/admin.6e49ad700d139e871ddd.js></script></body></html>