diff --git a/package.json b/package.json index 3fe02dd1..6f6634f6 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,9 @@ { "name": "vue-element-admin", - "version": "3.6.5", + "version": "3.6.6", "description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features", "author": "Pan ", "license": "MIT", - "private": true, "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js", @@ -12,6 +11,20 @@ "lint": "eslint --ext .js,.vue src", "test": "npm run lint" }, + "keywords": [ + "vue", + "element-ui", + "admin", + "management-system", + "admin-template" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/PanJiaChen/vue-element-admin.git" + }, + "bugs": { + "url": "https://github.com/PanJiaChen/vue-element-admin/issues" + }, "dependencies": { "axios": "0.17.1", "clipboard": "1.7.1", @@ -37,7 +50,7 @@ "vue-multiselect": "2.0.8", "vue-router": "3.0.1", "vue-splitpane": "1.0.2", - "vuedraggable": "2.15.0", + "vuedraggable": "^2.16.0", "vuex": "3.0.1", "xlsx": "0.11.16" }, diff --git a/src/components/Kanban/index.vue b/src/components/Kanban/index.vue new file mode 100644 index 00000000..c16894eb --- /dev/null +++ b/src/components/Kanban/index.vue @@ -0,0 +1,89 @@ + + + + diff --git a/src/components/ScrollBar/index.vue b/src/components/ScrollBar/index.vue deleted file mode 100644 index dc32f5c0..00000000 --- a/src/components/ScrollBar/index.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - - - diff --git a/src/directive/el-dragDialog/drag.js b/src/directive/el-dragDialog/drag.js index 7d49e4bb..3e3fb62a 100644 --- a/src/directive/el-dragDialog/drag.js +++ b/src/directive/el-dragDialog/drag.js @@ -2,39 +2,67 @@ export default{ bind(el, binding) { const dialogHeaderEl = el.querySelector('.el-dialog__header') const dragDom = el.querySelector('.el-dialog') - dialogHeaderEl.style = 'cursor:move;' + dialogHeaderEl.style.cssText += ';cursor:move;' + dragDom.style.cssText += ';top:0px;' // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); - const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null) + const getStyle = (function() { + if (window.document.currentStyle) { + return (dom, attr) => dom.currentStyle[attr] + } else { + return (dom, attr) => getComputedStyle(dom, false)[attr] + } + })() dialogHeaderEl.onmousedown = (e) => { // 鼠标按下,计算当前元素距离可视区的距离 const disX = e.clientX - dialogHeaderEl.offsetLeft const disY = e.clientY - dialogHeaderEl.offsetTop - // 获取到的值带px 正则匹配替换 - let styL, styT + const dragDomWidth = dragDom.offsetWidth + const dragDomheight = dragDom.offsetHeight - // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px - if (sty.left.includes('%')) { - styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) - styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) + const screenWidth = document.body.clientWidth + const screenHeight = document.body.clientHeight + + const minDragDomLeft = dragDom.offsetLeft + const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth + + const minDragDomTop = dragDom.offsetTop + const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight + + // 获取到的值带px 正则匹配替换 + let styL = getStyle(dragDom, 'left') + let styT = getStyle(dragDom, 'top') + + if (styL.includes('%')) { + styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100) + styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100) } else { - styL = +sty.left.replace(/\px/g, '') - styT = +sty.top.replace(/\px/g, '') + styL = +styL.replace(/\px/g, '') + styT = +styT.replace(/\px/g, '') } document.onmousemove = function(e) { // 通过事件委托,计算移动的距离 - const l = e.clientX - disX - const t = e.clientY - disY + let left = e.clientX - disX + let top = e.clientY - disY + + // 边界处理 + if (-(left) > minDragDomLeft) { + left = -minDragDomLeft + } else if (left > maxDragDomLeft) { + left = maxDragDomLeft + } + + if (-(top) > minDragDomTop) { + top = -minDragDomTop + } else if (top > maxDragDomTop) { + top = maxDragDomTop + } // 移动当前元素 - dragDom.style.left = `${l + styL}px` - dragDom.style.top = `${t + styT}px` - - // 将此时的位置传出去 - // binding.value({x:e.pageX,y:e.pageY}) + dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;` } document.onmouseup = function(e) { diff --git a/src/lang/en.js b/src/lang/en.js index c08c88ef..fc0405c9 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -19,6 +19,7 @@ export default { componentMixin: 'Mixin', backToTop: 'BackToTop', dragDialog: 'Drag Dialog', + dragKanban: 'Drag Kanban', charts: 'Charts', keyboardChart: 'Keyboard Chart', lineChart: 'Line Chart', diff --git a/src/lang/zh.js b/src/lang/zh.js index a4cc93d4..41c959c3 100644 --- a/src/lang/zh.js +++ b/src/lang/zh.js @@ -19,6 +19,7 @@ export default { componentMixin: '小组件', backToTop: '返回顶部', dragDialog: '拖拽 Dialog', + dragKanban: '可拖拽看板', charts: '图表', keyboardChart: '键盘图表', lineChart: '折线图', diff --git a/src/permission.js b/src/permission.js index 87a591e5..e4f491d1 100644 --- a/src/permission.js +++ b/src/permission.js @@ -31,10 +31,10 @@ router.beforeEach((to, from, next) => { router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record }) - }).catch(() => { + }).catch((err) => { store.dispatch('FedLogOut').then(() => { - Message.error('Verification failed, please login again') - next({ path: '/login' }) + Message.error(err || 'Verification failed, please login again') + next({ path: '/' }) }) }) } else { diff --git a/src/router/index.js b/src/router/index.js index a5d704ef..70e51d36 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -112,7 +112,8 @@ export const asyncRouterMap = [ { path: 'count-to', component: _import('components-demo/countTo'), name: 'countTo-demo', meta: { title: 'countTo' }}, { path: 'mixin', component: _import('components-demo/mixin'), name: 'componentMixin-demo', meta: { title: 'componentMixin' }}, { path: 'back-to-top', component: _import('components-demo/backToTop'), name: 'backToTop-demo', meta: { title: 'backToTop' }}, - { path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }} + { path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }}, + { path: 'drag-kanban', component: _import('components-demo/dragKanban'), name: 'dragKanban-demo', meta: { title: 'dragKanban' }} ] }, diff --git a/src/store/getters.js b/src/store/getters.js index 8adc5e81..d68251fd 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -1,6 +1,7 @@ const getters = { sidebar: state => state.app.sidebar, language: state => state.app.language, + device: state => state.app.device, visitedViews: state => state.tagsView.visitedViews, cachedViews: state => state.tagsView.cachedViews, token: state => state.user.token, diff --git a/src/store/modules/app.js b/src/store/modules/app.js index 9eed667c..d89664f8 100644 --- a/src/store/modules/app.js +++ b/src/store/modules/app.js @@ -3,8 +3,10 @@ import Cookies from 'js-cookie' const app = { state: { sidebar: { - opened: !+Cookies.get('sidebarStatus') + opened: !+Cookies.get('sidebarStatus'), + withoutAnimation: false }, + device: 'desktop', language: Cookies.get('language') || 'en' }, mutations: { @@ -15,6 +17,15 @@ const app = { Cookies.set('sidebarStatus', 0) } state.sidebar.opened = !state.sidebar.opened + state.sidebar.withoutAnimation = false + }, + CLOSE_SIDEBAR: (state, withoutAnimation) => { + Cookies.set('sidebarStatus', 1) + state.sidebar.opened = false + state.sidebar.withoutAnimation = withoutAnimation + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device }, SET_LANGUAGE: (state, language) => { state.language = language @@ -25,6 +36,12 @@ const app = { toggleSideBar({ commit }) { commit('TOGGLE_SIDEBAR') }, + closeSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + toggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + }, setLanguage({ commit }, language) { commit('SET_LANGUAGE', language) } diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 18c93570..13e76399 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -67,7 +67,13 @@ const user = { reject('error') } const data = response.data - commit('SET_ROLES', data.roles) + + if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', data.roles) + } else { + reject('getInfo: roles must be a non-null array !') + } + commit('SET_NAME', data.name) commit('SET_AVATAR', data.avatar) commit('SET_INTRODUCTION', data.introduction) diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index 36410770..26cece0c 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -7,10 +7,7 @@ } // 侧边栏 .sidebar-container { - .horizontal-collapse-transition { - transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; - } - transition: width .28s; + transition: width 0.28s; width: 180px !important; height: 100%; position: fixed; @@ -20,15 +17,30 @@ left: 0; z-index: 1001; overflow: hidden; + //reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + .scrollbar-wrapper { + height: calc(100% + 15px); + .el-scrollbar__view { + height: 100%; + } + } + .is-horizontal { + display: none; + } a { display: inline-block; width: 100%; + overflow: hidden; } .svg-icon { margin-right: 16px; } .el-menu { border: none; + height: 100%; width: 100% !important; } } @@ -47,23 +59,30 @@ } } .el-submenu { + overflow: hidden; &>.el-submenu__title { padding-left: 10px !important; - &>span { - height: 0; - width: 0; - overflow: hidden; - visibility: hidden; - display: inline-block; - } .el-submenu__icon-arrow { display: none; } } } + .el-menu--collapse { + .el-submenu { + &>.el-submenu__title { + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } } - .nest-menu .el-submenu>.el-submenu__title, - .el-submenu .el-menu-item { + .sidebar-container .nest-menu .el-submenu>.el-submenu__title, + .sidebar-container .el-submenu .el-menu-item { min-width: 180px !important; background-color: $subMenuBg !important; &:hover { @@ -73,4 +92,27 @@ .el-menu--collapse .el-menu .el-submenu { min-width: 180px !important; } + + //适配移动端 + .mobile { + .main-container { + margin-left: 0px; + } + .sidebar-container { + transition: transform .28s; + width: 180px !important; + } + &.hideSidebar { + .sidebar-container { + transition-duration: 0.3s; + transform: translate3d(-180px, 0, 0); + } + } + } + .withoutAnimation { + .main-container, + .sidebar-container { + transition: none; + } + } } diff --git a/src/views/components-demo/dragKanban.vue b/src/views/components-demo/dragKanban.vue new file mode 100644 index 00000000..2bbab2bd --- /dev/null +++ b/src/views/components-demo/dragKanban.vue @@ -0,0 +1,68 @@ + + + + diff --git a/src/views/dashboard/admin/components/TransactionTable.vue b/src/views/dashboard/admin/components/TransactionTable.vue index 90f4a914..4efb98f0 100644 --- a/src/views/dashboard/admin/components/TransactionTable.vue +++ b/src/views/dashboard/admin/components/TransactionTable.vue @@ -1,6 +1,6 @@