@@ -1,11 +1,23 @@
 | 
				
			|||||||
import Mock from 'mockjs'
 | 
					import Mock from 'mockjs'
 | 
				
			||||||
import mocks from './mocks'
 | 
					 | 
				
			||||||
import { param2Obj } from '../src/utils'
 | 
					import { param2Obj } from '../src/utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MOCK_API_BASE = '/mock'
 | 
					import user from './user'
 | 
				
			||||||
 | 
					import role from './role'
 | 
				
			||||||
 | 
					import article from './article'
 | 
				
			||||||
 | 
					import search from './remoteSearch'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mocks = [
 | 
				
			||||||
 | 
					  ...user,
 | 
				
			||||||
 | 
					  ...role,
 | 
				
			||||||
 | 
					  ...article,
 | 
				
			||||||
 | 
					  ...search
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// for front mock
 | 
				
			||||||
 | 
					// please use it cautiously, it will redefine XMLHttpRequest,
 | 
				
			||||||
 | 
					// which will cause many of your third-party libraries to be invalidated(like progress event).
 | 
				
			||||||
export function mockXHR() {
 | 
					export function mockXHR() {
 | 
				
			||||||
  // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
 | 
					  // mock patch
 | 
				
			||||||
  // https://github.com/nuysoft/Mock/issues/300
 | 
					  // https://github.com/nuysoft/Mock/issues/300
 | 
				
			||||||
  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
 | 
					  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
 | 
				
			||||||
  Mock.XHR.prototype.send = function() {
 | 
					  Mock.XHR.prototype.send = function() {
 | 
				
			||||||
@@ -42,9 +54,10 @@ export function mockXHR() {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// for mock server
 | 
				
			||||||
const responseFake = (url, type, respond) => {
 | 
					const responseFake = (url, type, respond) => {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    url: new RegExp(`${MOCK_API_BASE}${url}`),
 | 
					    url: new RegExp(`/mock${url}`),
 | 
				
			||||||
    type: type || 'get',
 | 
					    type: type || 'get',
 | 
				
			||||||
    response(req, res) {
 | 
					    response(req, res) {
 | 
				
			||||||
      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
 | 
					      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					const chokidar = require('chokidar')
 | 
				
			||||||
 | 
					const bodyParser = require('body-parser')
 | 
				
			||||||
 | 
					const chalk = require('chalk')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function registerRoutes(app) {
 | 
				
			||||||
 | 
					  const { default: mocks } = require('./index.js')
 | 
				
			||||||
 | 
					  for (const mock of mocks) {
 | 
				
			||||||
 | 
					    app[mock.type](mock.url, mock.response)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    mockRoutesLength: Object.keys(mocks).length
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function unregisterRoutes() {
 | 
				
			||||||
 | 
					  Object.keys(require.cache).forEach(i => {
 | 
				
			||||||
 | 
					    if (i.includes('/mock')) {
 | 
				
			||||||
 | 
					      delete require.cache[require.resolve(i)]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getPath(path) {
 | 
				
			||||||
 | 
					  var match = path.toString()
 | 
				
			||||||
 | 
					    .replace('\\/?', '')
 | 
				
			||||||
 | 
					    .replace('(?=\\/|$)', '$')
 | 
				
			||||||
 | 
					    .match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
 | 
				
			||||||
 | 
					  return match
 | 
				
			||||||
 | 
					    ? match[1].replace(/\\(.)/g, '$1').split('/')
 | 
				
			||||||
 | 
					    : path.toString()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getMockRoutesIndex(app) {
 | 
				
			||||||
 | 
					  for (let index = 0; index <= app._router.stack.length; index++) {
 | 
				
			||||||
 | 
					    const r = app._router.stack[index]
 | 
				
			||||||
 | 
					    if (r.route && r.route.path) {
 | 
				
			||||||
 | 
					      const path = getPath(r.route.path)
 | 
				
			||||||
 | 
					      if (path.includes('mock')) {
 | 
				
			||||||
 | 
					        return index
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = app => {
 | 
				
			||||||
 | 
					  // es6 polyfill
 | 
				
			||||||
 | 
					  require('@babel/register')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // parse app.body
 | 
				
			||||||
 | 
					  // http://expressjs.com/en/4x/api.html#req.body
 | 
				
			||||||
 | 
					  app.use(bodyParser.json())
 | 
				
			||||||
 | 
					  app.use(bodyParser.urlencoded({
 | 
				
			||||||
 | 
					    extended: true
 | 
				
			||||||
 | 
					  }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { mockRoutesLength } = registerRoutes(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // watch files, hot reload mock server
 | 
				
			||||||
 | 
					  chokidar.watch(('./mock'), {
 | 
				
			||||||
 | 
					    ignored: 'mock/mock-server.js',
 | 
				
			||||||
 | 
					    persistent: true,
 | 
				
			||||||
 | 
					    ignoreInitial: true
 | 
				
			||||||
 | 
					  }).on('all', (event, path) => {
 | 
				
			||||||
 | 
					    if (event === 'change' || event === 'add') {
 | 
				
			||||||
 | 
					      // find mock routes stack index
 | 
				
			||||||
 | 
					      const index = getMockRoutesIndex(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // remove mock routes stack
 | 
				
			||||||
 | 
					      app._router.stack.splice(index, mockRoutesLength)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // clear routes cache
 | 
				
			||||||
 | 
					      unregisterRoutes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      registerRoutes(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
import user from './user'
 | 
					 | 
				
			||||||
import role from './role'
 | 
					 | 
				
			||||||
import article from './article'
 | 
					 | 
				
			||||||
import search from './remoteSearch'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [
 | 
					 | 
				
			||||||
  ...user,
 | 
					 | 
				
			||||||
  ...role,
 | 
					 | 
				
			||||||
  ...article,
 | 
					 | 
				
			||||||
  ...search
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -82,6 +82,7 @@
 | 
				
			|||||||
    "babel-eslint": "10.0.1",
 | 
					    "babel-eslint": "10.0.1",
 | 
				
			||||||
    "babel-jest": "23.6.0",
 | 
					    "babel-jest": "23.6.0",
 | 
				
			||||||
    "chalk": "2.4.2",
 | 
					    "chalk": "2.4.2",
 | 
				
			||||||
 | 
					    "chokidar": "2.1.5",
 | 
				
			||||||
    "connect": "3.6.6",
 | 
					    "connect": "3.6.6",
 | 
				
			||||||
    "eslint": "5.15.3",
 | 
					    "eslint": "5.15.3",
 | 
				
			||||||
    "eslint-plugin-vue": "5.2.2",
 | 
					    "eslint-plugin-vue": "5.2.2",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
    <logo v-if="showLogo" :collapse="isCollapse" />
 | 
					    <logo v-if="showLogo" :collapse="isCollapse" />
 | 
				
			||||||
    <el-scrollbar wrap-class="scrollbar-wrapper">
 | 
					    <el-scrollbar wrap-class="scrollbar-wrapper">
 | 
				
			||||||
      <el-menu
 | 
					      <el-menu
 | 
				
			||||||
        :default-active="$route.path"
 | 
					        :default-active="activeMenu"
 | 
				
			||||||
        :collapse="isCollapse"
 | 
					        :collapse="isCollapse"
 | 
				
			||||||
        :background-color="variables.menuBg"
 | 
					        :background-color="variables.menuBg"
 | 
				
			||||||
        :text-color="variables.menuText"
 | 
					        :text-color="variables.menuText"
 | 
				
			||||||
@@ -30,6 +30,15 @@ export default {
 | 
				
			|||||||
      'permission_routes',
 | 
					      'permission_routes',
 | 
				
			||||||
      'sidebar'
 | 
					      'sidebar'
 | 
				
			||||||
    ]),
 | 
					    ]),
 | 
				
			||||||
 | 
					    activeMenu() {
 | 
				
			||||||
 | 
					      const route = this.$route
 | 
				
			||||||
 | 
					      const { meta, path } = route
 | 
				
			||||||
 | 
					      // if set path, the sidebar will highlight the path you set
 | 
				
			||||||
 | 
					      if (meta.activeMenu) {
 | 
				
			||||||
 | 
					        return meta.activeMenu
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return path
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    showLogo() {
 | 
					    showLogo() {
 | 
				
			||||||
      return this.$store.state.settings.sidebarLogo
 | 
					      return this.$store.state.settings.sidebarLogo
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,32 +12,32 @@ import chartsRouter from './modules/charts'
 | 
				
			|||||||
import tableRouter from './modules/table'
 | 
					import tableRouter from './modules/table'
 | 
				
			||||||
import nestedRouter from './modules/nested'
 | 
					import nestedRouter from './modules/nested'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** note: sub-menu only appear when children.length>=1
 | 
					 | 
				
			||||||
 *  detail see  https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
* hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
 | 
					 * Note: sub-menu only appear when route children.length >= 1
 | 
				
			||||||
* alwaysShow: true               if set true, will always show the root menu, whatever its child routes length
 | 
					 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
 | 
				
			||||||
*                                if not set alwaysShow, only more than one route under the children
 | 
					 *
 | 
				
			||||||
*                                it will becomes nested mode, otherwise not show the root menu
 | 
					 * hidden: true                   if set true, item will not show in the sidebar(default is false)
 | 
				
			||||||
* redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb
 | 
					 * alwaysShow: true               if set true, will always show the root menu
 | 
				
			||||||
* name:'router-name'             the name is used by <keep-alive> (must set!!!)
 | 
					 *                                if not set alwaysShow, when item has more than one children route,
 | 
				
			||||||
* meta : {
 | 
					 *                                it will becomes nested mode, otherwise not show the root menu
 | 
				
			||||||
    roles: ['admin','editor']    will control the page roles (you can set multiple roles)
 | 
					 * redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb
 | 
				
			||||||
    title: 'title'               the name show in sub-menu and breadcrumb (recommend set)
 | 
					 * 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'             the icon show in the sidebar
 | 
					    icon: 'svg-name'             the icon show in the sidebar
 | 
				
			||||||
    noCache: true                if true, the page will no be cached(default is false)
 | 
					    noCache: true                if set true, the page will no be cached(default is false)
 | 
				
			||||||
    breadcrumb: false            if false, the item will hidden in breadcrumb(default is true)
 | 
					    affix: true                  if set true, the tag will affix in the tags-view
 | 
				
			||||||
    affix: true                  if true, the tag will affix in the tags-view
 | 
					    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
 | 
					 * constantRoutes
 | 
				
			||||||
 * a base page that does not have permission requirements
 | 
					 * a base page that does not have permission requirements
 | 
				
			||||||
 * all roles can be accessed
 | 
					 * all roles can be accessed
 | 
				
			||||||
 * */
 | 
					 */
 | 
				
			||||||
export const constantRoutes = [
 | 
					export const constantRoutes = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: '/redirect',
 | 
					    path: '/redirect',
 | 
				
			||||||
@@ -113,7 +113,7 @@ export const constantRoutes = [
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * asyncRoutes
 | 
					 * asyncRoutes
 | 
				
			||||||
 * the routes that need to be dynamically loaded based on user roles
 | 
					 * the routes that need to be dynamically loaded based on user roles
 | 
				
			||||||
*/
 | 
					 */
 | 
				
			||||||
export const asyncRoutes = [
 | 
					export const asyncRoutes = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: '/permission',
 | 
					    path: '/permission',
 | 
				
			||||||
@@ -195,7 +195,7 @@ export const asyncRoutes = [
 | 
				
			|||||||
        path: 'edit/:id(\\d+)',
 | 
					        path: 'edit/:id(\\d+)',
 | 
				
			||||||
        component: () => import('@/views/example/edit'),
 | 
					        component: () => import('@/views/example/edit'),
 | 
				
			||||||
        name: 'EditArticle',
 | 
					        name: 'EditArticle',
 | 
				
			||||||
        meta: { title: 'editArticle', noCache: true },
 | 
					        meta: { title: 'editArticle', noCache: true, activeMenu: '/example/list' },
 | 
				
			||||||
        hidden: true
 | 
					        hidden: true
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,10 +28,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    .scrollbar-wrapper {
 | 
					    .scrollbar-wrapper {
 | 
				
			||||||
      overflow-x: hidden !important;
 | 
					      overflow-x: hidden !important;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      .el-scrollbar__view {
 | 
					 | 
				
			||||||
        height: 100%;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .el-scrollbar__bar.is-vertical {
 | 
					    .el-scrollbar__bar.is-vertical {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ service.interceptors.response.use(
 | 
				
			|||||||
    const res = response.data
 | 
					    const res = response.data
 | 
				
			||||||
    if (res.code !== 20000) {
 | 
					    if (res.code !== 20000) {
 | 
				
			||||||
      Message({
 | 
					      Message({
 | 
				
			||||||
        message: res.message,
 | 
					        message: res.message || 'error',
 | 
				
			||||||
        type: 'error',
 | 
					        type: 'error',
 | 
				
			||||||
        duration: 5 * 1000
 | 
					        duration: 5 * 1000
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
@@ -61,7 +61,7 @@ service.interceptors.response.use(
 | 
				
			|||||||
          })
 | 
					          })
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return Promise.reject('error')
 | 
					      return Promise.reject(res.message || 'error')
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return res
 | 
					      return res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,22 +41,7 @@ module.exports = {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    after(app) {
 | 
					    after: require('./mock/mock-server.js')
 | 
				
			||||||
      require('@babel/register')
 | 
					 | 
				
			||||||
      const bodyParser = require('body-parser')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // parse app.body
 | 
					 | 
				
			||||||
      // http://expressjs.com/en/4x/api.html#req.body
 | 
					 | 
				
			||||||
      app.use(bodyParser.json())
 | 
					 | 
				
			||||||
      app.use(bodyParser.urlencoded({
 | 
					 | 
				
			||||||
        extended: true
 | 
					 | 
				
			||||||
      }))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const { default: mocks } = require('./mock')
 | 
					 | 
				
			||||||
      for (const mock of mocks) {
 | 
					 | 
				
			||||||
        app[mock.type](mock.url, mock.response)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  configureWebpack: {
 | 
					  configureWebpack: {
 | 
				
			||||||
    // provide the app's title in webpack's name field, so that
 | 
					    // provide the app's title in webpack's name field, so that
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user