Browse Source

7.25-7.26: 菜单权限与按钮权限

test 2 years ago
parent
commit
a359631e56

+ 1 - 0
src/directives/index.js

xqd
@@ -0,0 +1 @@
+import './permission'

+ 33 - 0
src/directives/permission.js

xqd
@@ -0,0 +1,33 @@
+import Vue from 'vue'
+import $store from '@/store'
+
+function check(el, binding) {
+  const { value } = binding
+  const userInfo = $store.getters && $store.getters.userInfo
+  if (value && value instanceof Array) {
+    if (value.length > 0) {
+      let roles = []
+      const permissionRoles = value
+      if (userInfo.type === 1) {
+        roles = ['admin'] // 供应商
+      } else if (userInfo.type === 2) {
+        roles = ['salesman'] // 业务员
+      }
+      const hasPermission = roles.some(role => permissionRoles.includes(role))
+      if (!hasPermission) {
+        el.parentNode && el.parentNode.removeChild(el)
+      }
+    }
+  } else {
+    console.warn('need config Like v-permission="[\'admin\']" or v-permission="\'admin\'"')
+  }
+}
+
+Vue.directive('permission', {
+  inserted(el, binding) {
+    check(el, binding)
+  },
+  update(el, binding) {
+    check(el, binding)
+  }
+})

+ 1 - 1
src/main.js

xqd
@@ -12,7 +12,7 @@ import App from './App'
 import store from './store'
 import router from './router'
 import locale from 'element-ui/lib/locale/lang/zh-CN'
-
+import '@/directives'
 import '@/icons' // icon
 import '@/permission' // permission control
 import TableWrapper from '@/components/TableWrapper/TableWrapper.vue'

+ 17 - 7
src/permission.js

xqd xqd
@@ -21,14 +21,26 @@ router.beforeEach(async(to, from, next) => {
   const hasToken = getToken()
 
   if (hasToken) {
-    if (to.path === '/login') {
+    if (to.path === '/login' || to.path === '/register') {
       // if is logged in, redirect to the home page
       next()
       NProgress.done()
-    } else if (to.path === '/register') {
-      next()
     } else {
-      next()
+      try {
+        const userInfo = await $store.dispatch('user/ActionUserInfo')
+        $store.dispatch('permission/GenerateRoutes', userInfo).then(() => { // 生成可访问的路由表
+          router.addRoutes($store.getters.addRouters) // 动态添加可访问路由表
+          router.options.routes = $store.getters.addRouters
+          next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
+        })
+        next()
+      } catch (error) {
+        // remove token and go to login page to re-login
+        await $store.dispatch('user/resetToken')
+        Message.error(error || 'Has Error')
+        next(`/login?redirect=${to.path}`)
+        NProgress.done()
+      }
       // const hasGetUserInfo = $store.getters.name
       // if (hasGetUserInfo) {
       //   next()
@@ -55,9 +67,7 @@ router.beforeEach(async(to, from, next) => {
       next()
     } else {
       // other pages that do not have permission to access are redirected to the login page.
-      next({
-        name: 'login'
-      })
+      next({ name: 'login' })
       NProgress.done()
     }
   }

+ 371 - 0
src/router/index copy.js

xqd
@@ -0,0 +1,371 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+
+Vue.use(Router)
+
+/* Layout */
+import Layout from '@/layout'
+
+/**
+ * Note: sub-menu only appear when route children.length >= 1
+ * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
+ *
+ * hidden: true                   if set true, item will not show in the sidebar(default is false)
+ * alwaysShow: true               if set true, will always show the root menu
+ *                                if not set alwaysShow, when item has more than one children route,
+ *                                it will becomes nested mode, otherwise not show the root menu
+ * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
+ * name:'router-name'             the name is used by <keep-alive> (must set!!!)
+ * meta : {
+    roles: ['admin','editor']    control the page roles (you can set multiple roles)
+    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
+    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
+    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
+    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
+  }
+ */
+
+/**
+ * constantRoutes
+ * a base page that does not have permission requirements
+ * all roles can be accessed
+ */
+export const constantRoutes = [
+  {
+    path: '/login',
+    name: 'login',
+    component: () => import('@/views/login/index')
+    // hidden: true
+  },
+  {
+    path: '/register',
+    component: () => import('@/views/register/index')
+    // hidden: true
+  },
+  {
+    path: '/404',
+    component: () => import('@/views/404'),
+    hidden: true
+  },
+
+  // {
+  //   path: '/',
+  //   component: Layout,
+  //   redirect: '/dashboard',
+  //   children: [{
+  //     path: 'dashboard',
+  //     name: 'Dashboard',
+  //     component: () => import('@/views/dashboard/index'),
+  //     meta: { title: '合同列表', icon: 'dashboard' }
+  //   }]
+  // },
+  {
+    path: '/',
+    component: Layout,
+    redirect: '/contracts',
+    name: 'Example',
+    meta: { title: '合同列表', icon: 'el-icon-s-order' },
+    children: [
+      {
+        path: 'list',
+        name: 'contracts-list',
+        component: () => import('@/views/contracts/list'),
+        meta: { title: '合同列表', icon: 'el-icon-s-order' },
+        hidden: true
+      },
+      {
+        path: 'contracts',
+        name: 'contracts',
+        component: () => import('@/views/contracts/index'),
+        meta: { title: '合同列表', icon: 'el-icon-s-order' }
+
+      // hidden:true,
+      },
+      {
+        path: '/detail',
+        name: 'detail',
+        component: () => import('@/views/contracts/detail'),
+        meta: { title: '合同详情' },
+        hidden: true
+      },
+      // {
+      //   path: 'contracts/addcontract',
+      //   name: 'addcontract',
+      //  component: () => import('@/views/contracts/addcontract'),
+      //  meta: { title: '上传合同' },
+      //  hidden:true
+      // },
+      {
+        path: 'contracts/addnewbill',
+        name: 'addnewbill',
+        component: () => import('@/views/contracts/addnewbill'),
+        meta: { title: '新增汇票' },
+        hidden: true
+      },
+      {
+        path: 'contracts/billDetail',
+        name: 'billDetail',
+        component: () => import('@/views/contracts/billDetail'),
+        meta: { title: '汇票详情' },
+        hidden: true
+      },
+      {
+        path: 'contracts/addcontract',
+        name: 'addcontract',
+        component: () => import('@/views/contracts/new_file'),
+        meta: { title: '新增合同' },
+        hidden: true
+      }
+    ]
+  },
+
+  {
+    path: '/table',
+    component: Layout,
+    redirect: '/table',
+    name: 'Example',
+    meta: { title: '承兑人列表', icon: 'el-icon-s-help' },
+    children: [
+      {
+        path: 'table',
+        name: 'Table',
+        component: () => import('@/views/table/index'),
+        meta: { title: '承兑人列表', icon: 'el-icon-s-help' }
+      },
+      {
+        path: '/table/addAcceptor',
+        name: 'Table',
+        component: () => import('@/views/table/addAcceptor'),
+        meta: { title: '新增承兑人' },
+        hidden: true
+      },
+      {
+        path: 'table/detail',
+        name: 'Table',
+        component: () => import('@/views/table/detail'),
+        meta: { title: '承兑人详情' },
+        hidden: true
+      }
+    ]
+  },
+
+  {
+    path: '/form',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'Form',
+        component: () => import('@/views/form/index'),
+        meta: { title: '出票人列表', icon: 'form' }
+      },
+      {
+        path: '/form/addTicketdrawer',
+        name: 'addTicketdrawer',
+        component: () => import('@/views/form/addTicketdrawer'),
+        meta: { title: '新增出票人' },
+        hidden: true
+      },
+      {
+        path: '/form/detail',
+        name: 'detail',
+        component: () => import('@/views/form/detail'),
+        meta: { title: '出票人详情' },
+        hidden: true
+      }
+    ]
+  },
+  {
+    path: '/delivery',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'delivery',
+        component: () => import('@/views/delivery/index'),
+        meta: { title: '供应商账号', icon: 'el-icon-s-promotion' }
+      },
+      {
+        path: '/edit',
+        name: 'edit',
+        component: () => import('@/views/delivery/edit'),
+        meta: { title: '编辑' },
+        hidden: true
+      }
+    ]
+  },
+  // {
+  //   path: '/nested',
+  //   component: Layout,
+  //   redirect: '/nested/menu1',
+  //   name: 'Settlement',
+  //   meta: {
+  //     title: '供应商账号',
+  //     icon: 'nested'
+  //   },
+  //   children: [
+  //     {
+  //       path: 'menu1',
+  //       component: () => import('@/views/nested/menu1/index'), // Parent router-view
+  //       name: 'Menu1',
+  //       meta: { title: 'Menu1' },
+  //       children: [
+  //         {
+  //           path: 'menu1-1',
+  //           component: () => import('@/views/nested/menu1/menu1-1'),
+  //           name: 'Menu1-1',
+  //           meta: { title: 'Menu1-1' }
+  //         },
+  //         {
+  //           path: 'menu1-2',
+  //           component: () => import('@/views/nested/menu1/menu1-2'),
+  //           name: 'Menu1-2',
+  //           meta: { title: 'Menu1-2' },
+  //           children: [
+  //             {
+  //               path: 'menu1-2-1',
+  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
+  //               name: 'Menu1-2-1',
+  //               meta: { title: 'Menu1-2-1' }
+  //             },
+  //             {
+  //               path: 'menu1-2-2',
+  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
+  //               name: 'Menu1-2-2',
+  //               meta: { title: 'Menu1-2-2' }
+  //             }
+  //           ]
+  //         },
+  //         {
+  //           path: 'menu1-3',
+  //           component: () => import('@/views/nested/menu1/menu1-3'),
+  //           name: 'Menu1-3',
+  //           meta: { title: 'Menu1-3' }
+  //         }
+  //       ]
+  //     },
+  //     {
+  //       path: 'menu2',
+  //       component: () => import('@/views/nested/menu2/index'),
+  //       name: 'Menu2',
+  //       meta: { title: 'menu2' }
+  //     }
+  //   ]
+  // },
+
+  {
+    path: '/shipments',
+    component: Layout,
+    children: [
+      {
+        path: '/shipments/index',
+        name: 'shipments',
+        component: () => import('@/views/shipments/index'),
+        meta: { title: '报表统计', icon: 'el-icon-s-marketing' }
+      },
+      {
+        path: '/shipments1',
+        name: 'shipments1',
+        component: () => import('@/views/shipments/shipments1'),
+        meta: { title: '出票人分类报表' },
+        hidden: true
+      },
+      {
+        path: '/shipments2',
+        name: 'shipments2',
+        component: () => import('@/views/shipments/shipments2'),
+        meta: { title: '合同统计列表' },
+        hidden: true
+      },
+      {
+        path: '/shipments3',
+        name: 'shipments3',
+        component: () => import('@/views/shipments/shipments3'),
+        meta: { title: '供应商统计列表' },
+        hidden: true
+      }
+
+    ]
+  },
+  {
+    path: '/management',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'management',
+        component: () => import('@/views/management/index'),
+        meta: { title: '业务管理员', icon: 'el-icon-s-management' }
+      }
+    ]
+  },
+  {
+    path: '/sucuirtyaudit',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'sucuirtyaudit',
+        component: () => import('@/views/sucuirtyaudit/index'),
+        meta: { title: '安全审计', icon: 'el-icon-s-check' }
+      },
+      {
+        path: '/annexList',
+        name: 'annexList',
+        component: () => import('@/views/sucuirtyaudit/annexList'),
+        meta: { title: '附件列表' },
+        hidden: true
+      },
+      {
+        path: '/logdetail',
+        name: 'detail',
+        component: () => import('@/views/sucuirtyaudit/detail'),
+        meta: { title: '审计日志详情' },
+        hidden: true
+      }
+    ]
+  },
+  {
+    path: '/databackup',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'databackup',
+        component: () => import('@/views/databackup/index'),
+        meta: { title: '数据备份', icon: 'el-icon-upload' }
+      }
+    ]
+  },
+  {
+    path: '/mine',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'mine',
+        component: () => import('@/views/mine/index'),
+        meta: { title: '个人资料', icon: 'el-icon-s-custom' }
+      }
+    ]
+  },
+
+  // 404 page must be placed at the end !!!
+  { path: '*', redirect: '/404', hidden: true }
+]
+
+const createRouter = () => new Router({
+  // mode: 'history', // require service support
+  scrollBehavior: () => ({ y: 0 }),
+  routes: constantRoutes
+})
+
+const router = createRouter()
+
+// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
+export function resetRouter() {
+  const newRouter = createRouter()
+  router.matcher = newRouter.matcher // reset router
+}
+
+export default router

+ 59 - 139
src/router/index.js

xqd xqd xqd xqd xqd xqd xqd xqd xqd
@@ -2,111 +2,91 @@ import Vue from 'vue'
 import Router from 'vue-router'
 
 Vue.use(Router)
-
-/* Layout */
 import Layout from '@/layout'
 
-/**
- * Note: sub-menu only appear when route children.length >= 1
- * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
- *
- * hidden: true                   if set true, item will not show in the sidebar(default is false)
- * alwaysShow: true               if set true, will always show the root menu
- *                                if not set alwaysShow, when item has more than one children route,
- *                                it will becomes nested mode, otherwise not show the root menu
- * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
- * name:'router-name'             the name is used by <keep-alive> (must set!!!)
- * meta : {
-    roles: ['admin','editor']    control the page roles (you can set multiple roles)
-    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
-    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
-    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
-    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
-  }
- */
-
-/**
- * constantRoutes
- * a base page that does not have permission requirements
- * all roles can be accessed
- */
-export const constantRoutes = [
+export const constantRouterMap = [
+  {
+    path: '/',
+    component: Layout,
+    redirect: {
+      name: 'login'
+    }
+  },
   {
     path: '/login',
     name: 'login',
     component: () => import('@/views/login/index')
-    // hidden: true
   },
   {
     path: '/register',
     component: () => import('@/views/register/index')
-    // hidden: true
+  },
+  {
+    path: '/home',
+    component: Layout,
+    children: [
+      {
+        path: '/home',
+        component: () => import('@/views/home'),
+        hidden: true
+      }
+    ]
   },
   {
     path: '/404',
     component: () => import('@/views/404'),
     hidden: true
-  },
-
-  // {
-  //   path: '/',
-  //   component: Layout,
-  //   redirect: '/dashboard',
-  //   children: [{
-  //     path: 'dashboard',
-  //     name: 'Dashboard',
-  //     component: () => import('@/views/dashboard/index'),
-  //     meta: { title: '合同列表', icon: 'dashboard' }
-  //   }]
-  // },
+  }
+]
+export const asyncRouterMap = [
   {
-    path: '/',
+    path: '/contracts',
     component: Layout,
-    redirect: '/contracts',
     name: 'Example',
-    meta: { title: '合同列表', icon: 'el-icon-s-order' },
+    meta: { title: '合同列表', icon: 'el-icon-s-order', roles: ['admin'] },
+    redirect: {
+      name: 'contracts'
+    },
     children: [
       {
         path: 'list',
         name: 'contracts-list',
         component: () => import('@/views/contracts/list'),
-        meta: { title: '合同列表', icon: 'el-icon-s-order' },
+        meta: { title: '合同列表', icon: 'el-icon-s-order', roles: ['admin'] },
         hidden: true
       },
       {
         path: 'contracts',
         name: 'contracts',
         component: () => import('@/views/contracts/index'),
-        meta: { title: '合同列表', icon: 'el-icon-s-order' }
-
-      // hidden:true,
+        meta: { title: '合同列表', icon: 'el-icon-s-order', roles: ['admin'] }
       },
       {
         path: '/detail',
         name: 'detail',
         component: () => import('@/views/contracts/detail'),
-        meta: { title: '合同详情' },
+        meta: { title: '合同详情', roles: ['admin'] },
+        hidden: true
+      },
+      {
+        path: 'contracts/addcontract',
+        name: 'addcontract',
+        component: () => import('@/views/contracts/addcontract'),
+        meta: { title: '上传合同', roles: ['admin'] },
         hidden: true
       },
-      // {
-      //   path: 'contracts/addcontract',
-      //   name: 'addcontract',
-      //  component: () => import('@/views/contracts/addcontract'),
-      //  meta: { title: '上传合同' },
-      //  hidden:true
-      // },
       {
         path: 'contracts/addnewbill',
         name: 'addnewbill',
         component: () => import('@/views/contracts/addnewbill'),
-        meta: { title: '新增汇票' },
+        meta: { title: '新增汇票', roles: ['admin'] },
         hidden: true
       },
       {
         path: 'contracts/billDetail',
         name: 'billDetail',
         component: () => import('@/views/contracts/billDetail'),
-        meta: { title: '汇票详情' },
+        meta: { title: '汇票详情', roles: ['admin'] },
         hidden: true
       },
       {
@@ -124,26 +104,26 @@ export const constantRoutes = [
     component: Layout,
     redirect: '/table',
     name: 'Example',
-    meta: { title: '承兑人列表', icon: 'el-icon-s-help' },
+    meta: { title: '承兑人列表', icon: 'el-icon-s-help', roles: ['salesman'] },
     children: [
       {
         path: 'table',
         name: 'Table',
         component: () => import('@/views/table/index'),
-        meta: { title: '承兑人列表', icon: 'el-icon-s-help' }
+        meta: { title: '承兑人列表', icon: 'el-icon-s-help', roles: ['salesman'] }
       },
       {
         path: '/table/addAcceptor',
         name: 'Table',
         component: () => import('@/views/table/addAcceptor'),
-        meta: { title: '新增承兑人' },
+        meta: { title: '新增承兑人', roles: ['salesman'] },
         hidden: true
       },
       {
         path: 'table/detail',
         name: 'Table',
         component: () => import('@/views/table/detail'),
-        meta: { title: '承兑人详情' },
+        meta: { title: '承兑人详情', roles: ['salesman'] },
         hidden: true
       }
     ]
@@ -157,20 +137,20 @@ export const constantRoutes = [
         path: 'index',
         name: 'Form',
         component: () => import('@/views/form/index'),
-        meta: { title: '出票人列表', icon: 'form' }
+        meta: { title: '出票人列表', icon: 'form', roles: ['salesman'] }
       },
       {
         path: '/form/addTicketdrawer',
         name: 'addTicketdrawer',
         component: () => import('@/views/form/addTicketdrawer'),
-        meta: { title: '新增出票人' },
+        meta: { title: '新增出票人', roles: ['salesman'] },
         hidden: true
       },
       {
         path: '/form/detail',
         name: 'detail',
         component: () => import('@/views/form/detail'),
-        meta: { title: '出票人详情' },
+        meta: { title: '出票人详情', roles: ['salesman'] },
         hidden: true
       }
     ]
@@ -183,76 +163,17 @@ export const constantRoutes = [
         path: 'index',
         name: 'delivery',
         component: () => import('@/views/delivery/index'),
-        meta: { title: '供应商账号', icon: 'el-icon-s-promotion' }
+        meta: { title: '供应商账号', icon: 'el-icon-s-promotion', roles: ['salesman'] }
       },
       {
         path: '/edit',
         name: 'edit',
         component: () => import('@/views/delivery/edit'),
-        meta: { title: '编辑' },
+        meta: { title: '编辑', roles: ['salesman'] },
         hidden: true
       }
     ]
   },
-  // {
-  //   path: '/nested',
-  //   component: Layout,
-  //   redirect: '/nested/menu1',
-  //   name: 'Settlement',
-  //   meta: {
-  //     title: '供应商账号',
-  //     icon: 'nested'
-  //   },
-  //   children: [
-  //     {
-  //       path: 'menu1',
-  //       component: () => import('@/views/nested/menu1/index'), // Parent router-view
-  //       name: 'Menu1',
-  //       meta: { title: 'Menu1' },
-  //       children: [
-  //         {
-  //           path: 'menu1-1',
-  //           component: () => import('@/views/nested/menu1/menu1-1'),
-  //           name: 'Menu1-1',
-  //           meta: { title: 'Menu1-1' }
-  //         },
-  //         {
-  //           path: 'menu1-2',
-  //           component: () => import('@/views/nested/menu1/menu1-2'),
-  //           name: 'Menu1-2',
-  //           meta: { title: 'Menu1-2' },
-  //           children: [
-  //             {
-  //               path: 'menu1-2-1',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
-  //               name: 'Menu1-2-1',
-  //               meta: { title: 'Menu1-2-1' }
-  //             },
-  //             {
-  //               path: 'menu1-2-2',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
-  //               name: 'Menu1-2-2',
-  //               meta: { title: 'Menu1-2-2' }
-  //             }
-  //           ]
-  //         },
-  //         {
-  //           path: 'menu1-3',
-  //           component: () => import('@/views/nested/menu1/menu1-3'),
-  //           name: 'Menu1-3',
-  //           meta: { title: 'Menu1-3' }
-  //         }
-  //       ]
-  //     },
-  //     {
-  //       path: 'menu2',
-  //       component: () => import('@/views/nested/menu2/index'),
-  //       name: 'Menu2',
-  //       meta: { title: 'menu2' }
-  //     }
-  //   ]
-  // },
-
   {
     path: '/shipments',
     component: Layout,
@@ -261,27 +182,27 @@ export const constantRoutes = [
         path: '/shipments/index',
         name: 'shipments',
         component: () => import('@/views/shipments/index'),
-        meta: { title: '报表统计', icon: 'el-icon-s-marketing' }
+        meta: { title: '报表统计', icon: 'el-icon-s-marketing', roles: ['salesman'] }
       },
       {
         path: '/shipments1',
         name: 'shipments1',
         component: () => import('@/views/shipments/shipments1'),
-        meta: { title: '出票人分类报表' },
+        meta: { title: '出票人分类报表', roles: ['salesman'] },
         hidden: true
       },
       {
         path: '/shipments2',
         name: 'shipments2',
         component: () => import('@/views/shipments/shipments2'),
-        meta: { title: '合同统计列表' },
+        meta: { title: '合同统计列表', roles: ['salesman'] },
         hidden: true
       },
       {
         path: '/shipments3',
         name: 'shipments3',
         component: () => import('@/views/shipments/shipments3'),
-        meta: { title: '供应商统计列表' },
+        meta: { title: '供应商统计列表', roles: ['salesman'] },
         hidden: true
       }
 
@@ -295,7 +216,7 @@ export const constantRoutes = [
         path: 'index',
         name: 'management',
         component: () => import('@/views/management/index'),
-        meta: { title: '业务管理员', icon: 'el-icon-s-management' }
+        meta: { title: '业务管理员', icon: 'el-icon-s-management', roles: ['salesman'] }
       }
     ]
   },
@@ -307,20 +228,20 @@ export const constantRoutes = [
         path: 'index',
         name: 'sucuirtyaudit',
         component: () => import('@/views/sucuirtyaudit/index'),
-        meta: { title: '安全审计', icon: 'el-icon-s-check' }
+        meta: { title: '安全审计', icon: 'el-icon-s-check', roles: ['salesman'] }
       },
       {
         path: '/annexList',
         name: 'annexList',
         component: () => import('@/views/sucuirtyaudit/annexList'),
-        meta: { title: '附件列表' },
+        meta: { title: '附件列表', roles: ['salesman'] },
         hidden: true
       },
       {
         path: '/logdetail',
         name: 'detail',
         component: () => import('@/views/sucuirtyaudit/detail'),
-        meta: { title: '审计日志详情' },
+        meta: { title: '审计日志详情', roles: ['salesman'] },
         hidden: true
       }
     ]
@@ -333,7 +254,7 @@ export const constantRoutes = [
         path: 'index',
         name: 'databackup',
         component: () => import('@/views/databackup/index'),
-        meta: { title: '数据备份', icon: 'el-icon-upload' }
+        meta: { title: '数据备份', icon: 'el-icon-upload', roles: ['salesman'] }
       }
     ]
   },
@@ -345,19 +266,18 @@ export const constantRoutes = [
         path: 'index',
         name: 'mine',
         component: () => import('@/views/mine/index'),
-        meta: { title: '个人资料', icon: 'el-icon-s-custom' }
+        meta: { title: '个人资料', icon: 'el-icon-s-custom', roles: ['admin'] }
       }
     ]
   },
 
-  // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404', hidden: true }
 ]
 
 const createRouter = () => new Router({
   // mode: 'history', // require service support
   scrollBehavior: () => ({ y: 0 }),
-  routes: constantRoutes
+  routes: constantRouterMap
 })
 
 const router = createRouter()

+ 3 - 1
src/store/getters.js

xqd
@@ -3,6 +3,8 @@ const getters = {
   device: state => state.app.device,
   token: state => state.user.token,
   avatar: state => state.user.avatar,
-  name: state => state.user.name
+  name: state => state.user.name,
+  userInfo: state => state.user.userInfo,
+  addRouters: state => state.permission.addRouters
 }
 export default getters

+ 3 - 1
src/store/index.js

xqd xqd
@@ -4,6 +4,7 @@ import getters from './getters'
 import app from './modules/app'
 import settings from './modules/settings'
 import user from './modules/user'
+import permission from './modules/permission'
 
 Vue.use(Vuex)
 
@@ -11,7 +12,8 @@ const store = new Vuex.Store({
   modules: {
     app,
     settings,
-    user
+    user,
+    permission
   },
   getters
 })

+ 58 - 0
src/store/modules/permission.js

xqd
@@ -0,0 +1,58 @@
+import { asyncRouterMap, constantRouterMap } from '@/router'
+
+function hasPermission(roles, route) {
+  if (route.meta && route.meta.roles) {
+    return roles.some(role => route.meta.roles.indexOf(role) >= 0)
+  } else {
+    return true
+  }
+}
+
+const state = {
+  routers: constantRouterMap,
+  addRouters: []
+}
+const mutations = {
+  SET_ROUTERS: (state, routers) => {
+    state.addRouters = routers
+    state.routers = constantRouterMap.concat(routers)
+  }
+}
+const actions = {
+  GenerateRoutes({ commit }, data) {
+    return new Promise(resolve => {
+      let roles = []
+      if (data.type === 1) {
+        roles = ['admin'] // 供应商
+      } else if (data.type === 2) {
+        roles = ['salesman'] // 业务员
+      }
+      const accessedRouters = asyncRouterMap.filter(v => {
+        if (hasPermission(roles, v)) {
+          if (v.children && v.children.length > 0) {
+            v.children = v.children.filter(child => {
+              if (hasPermission(roles, child)) {
+                return child
+              }
+              return false
+            })
+            return v
+          } else {
+            return v
+          }
+        }
+        return false
+      })
+      commit('SET_ROUTERS', accessedRouters)
+      resolve()
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}
+

+ 4 - 5
src/store/modules/user.js

xqd xqd xqd xqd
@@ -1,7 +1,6 @@
 import {
   login,
-  logout,
-  getInfo
+  logout
 } from '@/api/user'
 import {
   getToken,
@@ -21,7 +20,7 @@ const getDefaultState = () => {
     name: '',
     avatar: '',
     checked: '',
-    userInfo: getUserInfo() || {}
+    userInfo: getUserInfo() ? JSON.parse(getUserInfo()) : {}
   }
 }
 
@@ -63,7 +62,7 @@ const actions = {
         setToken(token)
         setUserInfo(userInfo)
         $router.push({
-          path: '/'
+          path: '/contracts'
         })
       }
     })
@@ -74,7 +73,7 @@ const actions = {
       if (Object.keys(state.userInfo).length > 0) {
         resolve(state.userInfo)
       } else if (getUserInfo()) {
-        resolve(getUserInfo)
+        resolve(getUserInfo())
       } else {
         reject()
       }

+ 3 - 4
src/views/contracts/index.vue

xqd xqd xqd xqd
@@ -61,7 +61,7 @@
           </el-dropdown-menu>
         </el-dropdown>
       </div>
-      <div class="grid-content bg-purple">
+      <!-- <div class="grid-content bg-purple">
         <div class="block">
           <el-date-picker
             v-model="value2"
@@ -75,7 +75,7 @@
             value-format="yyyy-MM-dd"
           />
         </div>
-      </div>
+      </div> -->
     </el-row>
 
     <el-table
@@ -113,7 +113,7 @@
     <div style="display: flex;justify-content: space-between;">
       <el-row type="flex" justify="space-between">
         <div class="btn" style="display: flex; justify-content: flex-end">
-          <el-button  type="primary" @click="addNewContract">上传合同</el-button>
+          <el-button v-permission="['admin']" type="primary" @click="addNewContract">上传合同</el-button>
           <el-button v-if="checked === 0" type="primary" @click="failed">审核失败</el-button>
           <el-button v-if="checked === 0" type="primary" @click="successed">审核成功</el-button>
           <el-button type="primary" @click="Exports">批量导出</el-button>
@@ -226,7 +226,6 @@ export default {
   },
   mounted() {
     this.checked = this.$store.state.user.checked
-	console.log(this.checked)
     // this.$request({
     //   url: '/api/Contract/search',
     //   method: 'post',

+ 29 - 0
src/views/home/index.vue

xqd
@@ -0,0 +1,29 @@
+<template>
+  <div class="home">
+    <p>你好,{{ userInfo.name || userInfo.account }}</p>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+
+export default {
+  name: 'Home',
+  computed: {
+    ...mapState('user', ['userInfo'])
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.home{
+  min-height: calc(100vh - 140px);
+  padding-top: 50px;
+  background-color: #ffffff;
+  text-align: center;
+  p{
+    padding: 50px;
+    font-size: 32px;
+  }
+}
+</style>