ソースを参照

修改密码逻辑,删除无用代码

xiaoxin 3 年 前
コミット
662563d62b
85 ファイル変更216 行追加6038 行削除
  1. 0 21
      LICENSE
  2. 0 116
      mock/article.js
  3. 0 60
      mock/index.js
  4. 0 81
      mock/mock-server.js
  5. 0 51
      mock/remote-search.js
  6. 0 98
      mock/role/index.js
  7. 0 530
      mock/role/routes.js
  8. 0 84
      mock/user.js
  9. 0 48
      mock/utils.js
  10. 0 42
      src/api/article.js
  11. 0 8
      src/api/qiniu.js
  12. 0 17
      src/api/remote-search.js
  13. 0 38
      src/api/role.js
  14. 0 145
      src/components/RightPanel/index.vue
  15. 0 108
      src/layout/components/Settings/index.vue
  16. 47 49
      src/layout/index.vue
  17. 0 275
      src/router/index.js
  18. 0 36
      src/router/modules/charts.js
  19. 0 102
      src/router/modules/components.js
  20. 0 66
      src/router/modules/nested.js
  21. 0 41
      src/router/modules/table.js
  22. 0 23
      src/views/charts/keyboard.vue
  23. 0 23
      src/views/charts/line.vue
  24. 0 23
      src/views/charts/mix-chart.vue
  25. 0 61
      src/views/components-demo/avatar-upload.vue
  26. 0 154
      src/views/components-demo/back-to-top.vue
  27. 0 218
      src/views/components-demo/count-to.vue
  28. 0 39
      src/views/components-demo/dnd-list.vue
  29. 0 61
      src/views/components-demo/drag-dialog.vue
  30. 0 66
      src/views/components-demo/drag-kanban.vue
  31. 0 43
      src/views/components-demo/drag-select.vue
  32. 0 31
      src/views/components-demo/dropzone.vue
  33. 0 36
      src/views/components-demo/json-editor.vue
  34. 0 101
      src/views/components-demo/markdown.vue
  35. 0 169
      src/views/components-demo/mixin.vue
  36. 0 67
      src/views/components-demo/split-pane.vue
  37. 0 135
      src/views/components-demo/sticky.vue
  38. 0 36
      src/views/components-demo/tinymce.vue
  39. 0 13
      src/views/error-log/components/ErrorTestA.vue
  40. 0 11
      src/views/error-log/components/ErrorTestB.vue
  41. 0 32
      src/views/error-log/index.vue
  42. 0 289
      src/views/example/components/ArticleDetail.vue
  43. 0 41
      src/views/example/components/Dropdown/Comment.vue
  44. 0 46
      src/views/example/components/Dropdown/Platform.vue
  45. 0 38
      src/views/example/components/Dropdown/SourceUrl.vue
  46. 0 3
      src/views/example/components/Dropdown/index.js
  47. 0 13
      src/views/example/components/Warning.vue
  48. 0 13
      src/views/example/create.vue
  49. 0 13
      src/views/example/edit.vue
  50. 0 112
      src/views/example/list.vue
  51. 0 34
      src/views/excel/components/AutoWidthOption.vue
  52. 0 39
      src/views/excel/components/BookTypeOption.vue
  53. 0 27
      src/views/excel/components/FilenameOption.vue
  54. 0 116
      src/views/excel/export-excel.vue
  55. 0 101
      src/views/excel/merge-header.vue
  56. 0 107
      src/views/excel/select-excel.vue
  57. 0 42
      src/views/excel/upload-excel.vue
  58. 53 53
      src/views/login/index.vue
  59. 0 7
      src/views/nested/menu1/index.vue
  60. 0 7
      src/views/nested/menu1/menu1-1/index.vue
  61. 0 7
      src/views/nested/menu1/menu1-2/index.vue
  62. 0 5
      src/views/nested/menu1/menu1-2/menu1-2-1/index.vue
  63. 0 5
      src/views/nested/menu1/menu1-2/menu1-2-2/index.vue
  64. 0 5
      src/views/nested/menu1/menu1-3/index.vue
  65. 0 5
      src/views/nested/menu2/index.vue
  66. 0 58
      src/views/pdf/content.js
  67. 0 201
      src/views/pdf/download.vue
  68. 0 13
      src/views/pdf/index.vue
  69. 0 41
      src/views/qiniu/upload.vue
  70. 0 103
      src/views/tab/components/TabPane.vue
  71. 0 57
      src/views/tab/index.vue
  72. 0 379
      src/views/table/complex-table.vue
  73. 0 153
      src/views/table/drag-table.vue
  74. 0 62
      src/views/table/dynamic-table/components/FixedThead.vue
  75. 0 50
      src/views/table/dynamic-table/components/UnfixedThead.vue
  76. 0 24
      src/views/table/dynamic-table/index.vue
  77. 0 149
      src/views/table/inline-edit-table.vue
  78. 116 109
      src/views/user/index.vue
  79. 0 5
      tests/unit/.eslintrc.js
  80. 0 18
      tests/unit/components/Hamburger.spec.js
  81. 0 22
      tests/unit/components/SvgIcon.spec.js
  82. 0 29
      tests/unit/utils/formatTime.spec.js
  83. 0 14
      tests/unit/utils/param2Obj.spec.js
  84. 0 37
      tests/unit/utils/parseTime.spec.js
  85. 0 28
      tests/unit/utils/validate.spec.js

+ 0 - 21
LICENSE

@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017-present PanJiaChen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.

+ 0 - 116
mock/article.js

@@ -1,116 +0,0 @@
-const Mock = require('mockjs')
-
-const List = []
-const count = 100
-
-const baseContent = '<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
-const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'
-
-for (let i = 0; i < count; i++) {
-  List.push(Mock.mock({
-    id: '@increment',
-    timestamp: +Mock.Random.date('T'),
-    author: '@first',
-    reviewer: '@first',
-    title: '@title(5, 10)',
-    content_short: 'mock data',
-    content: baseContent,
-    forecast: '@float(0, 100, 2, 2)',
-    importance: '@integer(1, 3)',
-    'type|1': ['CN', 'US', 'JP', 'EU'],
-    'status|1': ['published', 'draft'],
-    display_time: '@datetime',
-    comment_disabled: true,
-    pageviews: '@integer(300, 5000)',
-    image_uri,
-    platforms: ['a-platform']
-  }))
-}
-
-module.exports = [
-  {
-    url: '/vue-element-admin/article/list',
-    type: 'get',
-    response: config => {
-      const { importance, type, title, page = 1, limit = 20, sort } = config.query
-
-      let mockList = List.filter(item => {
-        if (importance && item.importance !== +importance) return false
-        if (type && item.type !== type) return false
-        if (title && item.title.indexOf(title) < 0) return false
-        return true
-      })
-
-      if (sort === '-id') {
-        mockList = mockList.reverse()
-      }
-
-      const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
-
-      return {
-        code: 20000,
-        data: {
-          total: mockList.length,
-          items: pageList
-        }
-      }
-    }
-  },
-
-  {
-    url: '/vue-element-admin/article/detail',
-    type: 'get',
-    response: config => {
-      const { id } = config.query
-      for (const article of List) {
-        if (article.id === +id) {
-          return {
-            code: 20000,
-            data: article
-          }
-        }
-      }
-    }
-  },
-
-  {
-    url: '/vue-element-admin/article/pv',
-    type: 'get',
-    response: _ => {
-      return {
-        code: 20000,
-        data: {
-          pvData: [
-            { key: 'PC', pv: 1024 },
-            { key: 'mobile', pv: 1024 },
-            { key: 'ios', pv: 1024 },
-            { key: 'android', pv: 1024 }
-          ]
-        }
-      }
-    }
-  },
-
-  {
-    url: '/vue-element-admin/article/create',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        data: 'success'
-      }
-    }
-  },
-
-  {
-    url: '/vue-element-admin/article/update',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        data: 'success'
-      }
-    }
-  }
-]
-

+ 0 - 60
mock/index.js

@@ -1,60 +0,0 @@
-const Mock = require('mockjs')
-const { param2Obj } = require('./utils')
-
-const user = require('./user')
-const role = require('./role')
-const article = require('./article')
-const search = require('./remote-search')
-
-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).
-function mockXHR() {
-  // mock patch
-  // https://github.com/nuysoft/Mock/issues/300
-  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
-  Mock.XHR.prototype.send = function() {
-    if (this.custom.xhr) {
-      this.custom.xhr.withCredentials = this.withCredentials || false
-
-      if (this.responseType) {
-        this.custom.xhr.responseType = this.responseType
-      }
-    }
-    this.proxy_send(...arguments)
-  }
-
-  function XHR2ExpressReqWrap(respond) {
-    return function(options) {
-      let result = null
-      if (respond instanceof Function) {
-        const { body, type, url } = options
-        // https://expressjs.com/en/4x/api.html#req
-        result = respond({
-          method: type,
-          body: JSON.parse(body),
-          query: param2Obj(url)
-        })
-      } else {
-        result = respond
-      }
-      return Mock.mock(result)
-    }
-  }
-
-  for (const i of mocks) {
-    Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
-  }
-}
-
-module.exports = {
-  mocks,
-  mockXHR
-}

+ 0 - 81
mock/mock-server.js

@@ -1,81 +0,0 @@
-const chokidar = require('chokidar')
-const bodyParser = require('body-parser')
-const chalk = require('chalk')
-const path = require('path')
-const Mock = require('mockjs')
-
-const mockDir = path.join(process.cwd(), 'mock')
-
-function registerRoutes(app) {
-  let mockLastIndex
-  const { mocks } = require('./index.js')
-  const mocksForServer = mocks.map(route => {
-    return responseFake(route.url, route.type, route.response)
-  })
-  for (const mock of mocksForServer) {
-    app[mock.type](mock.url, mock.response)
-    mockLastIndex = app._router.stack.length
-  }
-  const mockRoutesLength = Object.keys(mocksForServer).length
-  return {
-    mockRoutesLength: mockRoutesLength,
-    mockStartIndex: mockLastIndex - mockRoutesLength
-  }
-}
-
-function unregisterRoutes() {
-  Object.keys(require.cache).forEach(i => {
-    if (i.includes(mockDir)) {
-      delete require.cache[require.resolve(i)]
-    }
-  })
-}
-
-// for mock server
-const responseFake = (url, type, respond) => {
-  return {
-    url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
-    type: type || 'get',
-    response(req, res) {
-      console.log('request invoke:' + req.path)
-      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
-    }
-  }
-}
-
-module.exports = app => {
-  // parse app.body
-  // https://expressjs.com/en/4x/api.html#req.body
-  app.use(bodyParser.json())
-  app.use(bodyParser.urlencoded({
-    extended: true
-  }))
-
-  const mockRoutes = registerRoutes(app)
-  var mockRoutesLength = mockRoutes.mockRoutesLength
-  var mockStartIndex = mockRoutes.mockStartIndex
-
-  // watch files, hot reload mock server
-  chokidar.watch(mockDir, {
-    ignored: /mock-server/,
-    ignoreInitial: true
-  }).on('all', (event, path) => {
-    if (event === 'change' || event === 'add') {
-      try {
-        // remove mock routes stack
-        app._router.stack.splice(mockStartIndex, mockRoutesLength)
-
-        // clear routes cache
-        unregisterRoutes()
-
-        const mockRoutes = registerRoutes(app)
-        mockRoutesLength = mockRoutes.mockRoutesLength
-        mockStartIndex = mockRoutes.mockStartIndex
-
-        console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
-      } catch (error) {
-        console.log(chalk.redBright(error))
-      }
-    }
-  })
-}

+ 0 - 51
mock/remote-search.js

@@ -1,51 +0,0 @@
-const Mock = require('mockjs')
-
-const NameList = []
-const count = 100
-
-for (let i = 0; i < count; i++) {
-  NameList.push(Mock.mock({
-    name: '@first'
-  }))
-}
-NameList.push({ name: 'mock-Pan' })
-
-module.exports = [
-  // username search
-  {
-    url: '/vue-element-admin/search/user',
-    type: 'get',
-    response: config => {
-      const { name } = config.query
-      const mockNameList = NameList.filter(item => {
-        const lowerCaseName = item.name.toLowerCase()
-        return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0)
-      })
-      return {
-        code: 20000,
-        data: { items: mockNameList }
-      }
-    }
-  },
-
-  // transaction list
-  {
-    url: '/vue-element-admin/transaction/list',
-    type: 'get',
-    response: _ => {
-      return {
-        code: 20000,
-        data: {
-          total: 20,
-          'items|20': [{
-            order_no: '@guid()',
-            timestamp: +Mock.Random.date('T'),
-            username: '@name()',
-            price: '@float(1000, 15000, 0, 2)',
-            'status|1': ['success', 'pending']
-          }]
-        }
-      }
-    }
-  }
-]

+ 0 - 98
mock/role/index.js

@@ -1,98 +0,0 @@
-const Mock = require('mockjs')
-const { deepClone } = require('../utils')
-const { asyncRoutes, constantRoutes } = require('./routes.js')
-
-const routes = deepClone([...constantRoutes, ...asyncRoutes])
-
-const roles = [
-  {
-    key: 'admin',
-    name: 'admin',
-    description: 'Super Administrator. Have access to view all pages.',
-    routes: routes
-  },
-  {
-    key: 'editor',
-    name: 'editor',
-    description: 'Normal Editor. Can see all pages except permission page',
-    routes: routes.filter(i => i.path !== '/permission')// just a mock
-  },
-  {
-    key: 'visitor',
-    name: 'visitor',
-    description: 'Just a visitor. Can only see the home page and the document page',
-    routes: [{
-      path: '',
-      redirect: 'dashboard',
-      children: [
-        {
-          path: 'dashboard',
-          name: 'Dashboard',
-          meta: { title: 'dashboard', icon: 'dashboard' }
-        }
-      ]
-    }]
-  }
-]
-
-module.exports = [
-  // mock get all routes form server
-  {
-    url: '/vue-element-admin/routes',
-    type: 'get',
-    response: _ => {
-      return {
-        code: 20000,
-        data: routes
-      }
-    }
-  },
-
-  // mock get all roles form server
-  {
-    url: '/vue-element-admin/roles',
-    type: 'get',
-    response: _ => {
-      return {
-        code: 20000,
-        data: roles
-      }
-    }
-  },
-
-  // add role
-  {
-    url: '/vue-element-admin/role',
-    type: 'post',
-    response: {
-      code: 20000,
-      data: {
-        key: Mock.mock('@integer(300, 5000)')
-      }
-    }
-  },
-
-  // update role
-  {
-    url: '/vue-element-admin/role/[A-Za-z0-9]',
-    type: 'put',
-    response: {
-      code: 20000,
-      data: {
-        status: 'success'
-      }
-    }
-  },
-
-  // delete role
-  {
-    url: '/vue-element-admin/role/[A-Za-z0-9]',
-    type: 'delete',
-    response: {
-      code: 20000,
-      data: {
-        status: 'success'
-      }
-    }
-  }
-]

+ 0 - 530
mock/role/routes.js

@@ -1,530 +0,0 @@
-// Just a mock data
-
-const constantRoutes = [
-  {
-    path: '/redirect',
-    component: 'layout/Layout',
-    hidden: true,
-    children: [
-      {
-        path: '/redirect/:path*',
-        component: 'views/redirect/index'
-      }
-    ]
-  },
-  {
-    path: '/login',
-    component: 'views/login/index',
-    hidden: true
-  },
-  {
-    path: '/auth-redirect',
-    component: 'views/login/auth-redirect',
-    hidden: true
-  },
-  {
-    path: '/404',
-    component: 'views/error-page/404',
-    hidden: true
-  },
-  {
-    path: '/401',
-    component: 'views/error-page/401',
-    hidden: true
-  },
-  {
-    path: '',
-    component: 'layout/Layout',
-    redirect: 'dashboard',
-    children: [
-      {
-        path: 'dashboard',
-        component: 'views/dashboard/index',
-        name: 'Dashboard',
-        meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
-      }
-    ]
-  },
-  {
-    path: '/documentation',
-    component: 'layout/Layout',
-    children: [
-      {
-        path: 'index',
-        component: 'views/documentation/index',
-        name: 'Documentation',
-        meta: { title: 'Documentation', icon: 'documentation', affix: true }
-      }
-    ]
-  },
-  {
-    path: '/guide',
-    component: 'layout/Layout',
-    redirect: '/guide/index',
-    children: [
-      {
-        path: 'index',
-        component: 'views/guide/index',
-        name: 'Guide',
-        meta: { title: 'Guide', icon: 'guide', noCache: true }
-      }
-    ]
-  }
-]
-
-const asyncRoutes = [
-  {
-    path: '/permission',
-    component: 'layout/Layout',
-    redirect: '/permission/index',
-    alwaysShow: true,
-    meta: {
-      title: 'Permission',
-      icon: 'lock',
-      roles: ['admin', 'editor']
-    },
-    children: [
-      {
-        path: 'page',
-        component: 'views/permission/page',
-        name: 'PagePermission',
-        meta: {
-          title: 'Page Permission',
-          roles: ['admin']
-        }
-      },
-      {
-        path: 'directive',
-        component: 'views/permission/directive',
-        name: 'DirectivePermission',
-        meta: {
-          title: 'Directive Permission'
-        }
-      },
-      {
-        path: 'role',
-        component: 'views/permission/role',
-        name: 'RolePermission',
-        meta: {
-          title: 'Role Permission',
-          roles: ['admin']
-        }
-      }
-    ]
-  },
-
-  {
-    path: '/icon',
-    component: 'layout/Layout',
-    children: [
-      {
-        path: 'index',
-        component: 'views/icons/index',
-        name: 'Icons',
-        meta: { title: 'Icons', icon: 'icon', noCache: true }
-      }
-    ]
-  },
-
-  {
-    path: '/components',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    name: 'ComponentDemo',
-    meta: {
-      title: 'Components',
-      icon: 'component'
-    },
-    children: [
-      {
-        path: 'tinymce',
-        component: 'views/components-demo/tinymce',
-        name: 'TinymceDemo',
-        meta: { title: 'Tinymce' }
-      },
-      {
-        path: 'markdown',
-        component: 'views/components-demo/markdown',
-        name: 'MarkdownDemo',
-        meta: { title: 'Markdown' }
-      },
-      {
-        path: 'json-editor',
-        component: 'views/components-demo/json-editor',
-        name: 'JsonEditorDemo',
-        meta: { title: 'Json Editor' }
-      },
-      {
-        path: 'split-pane',
-        component: 'views/components-demo/split-pane',
-        name: 'SplitpaneDemo',
-        meta: { title: 'SplitPane' }
-      },
-      {
-        path: 'avatar-upload',
-        component: 'views/components-demo/avatar-upload',
-        name: 'AvatarUploadDemo',
-        meta: { title: 'Avatar Upload' }
-      },
-      {
-        path: 'dropzone',
-        component: 'views/components-demo/dropzone',
-        name: 'DropzoneDemo',
-        meta: { title: 'Dropzone' }
-      },
-      {
-        path: 'sticky',
-        component: 'views/components-demo/sticky',
-        name: 'StickyDemo',
-        meta: { title: 'Sticky' }
-      },
-      {
-        path: 'count-to',
-        component: 'views/components-demo/count-to',
-        name: 'CountToDemo',
-        meta: { title: 'Count To' }
-      },
-      {
-        path: 'mixin',
-        component: 'views/components-demo/mixin',
-        name: 'ComponentMixinDemo',
-        meta: { title: 'componentMixin' }
-      },
-      {
-        path: 'back-to-top',
-        component: 'views/components-demo/back-to-top',
-        name: 'BackToTopDemo',
-        meta: { title: 'Back To Top' }
-      },
-      {
-        path: 'drag-dialog',
-        component: 'views/components-demo/drag-dialog',
-        name: 'DragDialogDemo',
-        meta: { title: 'Drag Dialog' }
-      },
-      {
-        path: 'drag-select',
-        component: 'views/components-demo/drag-select',
-        name: 'DragSelectDemo',
-        meta: { title: 'Drag Select' }
-      },
-      {
-        path: 'dnd-list',
-        component: 'views/components-demo/dnd-list',
-        name: 'DndListDemo',
-        meta: { title: 'Dnd List' }
-      },
-      {
-        path: 'drag-kanban',
-        component: 'views/components-demo/drag-kanban',
-        name: 'DragKanbanDemo',
-        meta: { title: 'Drag Kanban' }
-      }
-    ]
-  },
-  {
-    path: '/charts',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    name: 'Charts',
-    meta: {
-      title: 'Charts',
-      icon: 'chart'
-    },
-    children: [
-      {
-        path: 'keyboard',
-        component: 'views/charts/keyboard',
-        name: 'KeyboardChart',
-        meta: { title: 'Keyboard Chart', noCache: true }
-      },
-      {
-        path: 'line',
-        component: 'views/charts/line',
-        name: 'LineChart',
-        meta: { title: 'Line Chart', noCache: true }
-      },
-      {
-        path: 'mixchart',
-        component: 'views/charts/mixChart',
-        name: 'MixChart',
-        meta: { title: 'Mix Chart', noCache: true }
-      }
-    ]
-  },
-  {
-    path: '/nested',
-    component: 'layout/Layout',
-    redirect: '/nested/menu1/menu1-1',
-    name: 'Nested',
-    meta: {
-      title: 'Nested',
-      icon: 'nested'
-    },
-    children: [
-      {
-        path: 'menu1',
-        component: 'views/nested/menu1/index',
-        name: 'Menu1',
-        meta: { title: 'Menu1' },
-        redirect: '/nested/menu1/menu1-1',
-        children: [
-          {
-            path: 'menu1-1',
-            component: 'views/nested/menu1/menu1-1',
-            name: 'Menu1-1',
-            meta: { title: 'Menu1-1' }
-          },
-          {
-            path: 'menu1-2',
-            component: 'views/nested/menu1/menu1-2',
-            name: 'Menu1-2',
-            redirect: '/nested/menu1/menu1-2/menu1-2-1',
-            meta: { title: 'Menu1-2' },
-            children: [
-              {
-                path: 'menu1-2-1',
-                component: 'views/nested/menu1/menu1-2/menu1-2-1',
-                name: 'Menu1-2-1',
-                meta: { title: 'Menu1-2-1' }
-              },
-              {
-                path: 'menu1-2-2',
-                component: 'views/nested/menu1/menu1-2/menu1-2-2',
-                name: 'Menu1-2-2',
-                meta: { title: 'Menu1-2-2' }
-              }
-            ]
-          },
-          {
-            path: 'menu1-3',
-            component: 'views/nested/menu1/menu1-3',
-            name: 'Menu1-3',
-            meta: { title: 'Menu1-3' }
-          }
-        ]
-      },
-      {
-        path: 'menu2',
-        name: 'Menu2',
-        component: 'views/nested/menu2/index',
-        meta: { title: 'Menu2' }
-      }
-    ]
-  },
-
-  {
-    path: '/example',
-    component: 'layout/Layout',
-    redirect: '/example/list',
-    name: 'Example',
-    meta: {
-      title: 'Example',
-      icon: 'example'
-    },
-    children: [
-      {
-        path: 'create',
-        component: 'views/example/create',
-        name: 'CreateArticle',
-        meta: { title: 'Create Article', icon: 'edit' }
-      },
-      {
-        path: 'edit/:id(\\d+)',
-        component: 'views/example/edit',
-        name: 'EditArticle',
-        meta: { title: 'Edit Article', noCache: true },
-        hidden: true
-      },
-      {
-        path: 'list',
-        component: 'views/example/list',
-        name: 'ArticleList',
-        meta: { title: 'Article List', icon: 'list' }
-      }
-    ]
-  },
-
-  {
-    path: '/tab',
-    component: 'layout/Layout',
-    children: [
-      {
-        path: 'index',
-        component: 'views/tab/index',
-        name: 'Tab',
-        meta: { title: 'Tab', icon: 'tab' }
-      }
-    ]
-  },
-
-  {
-    path: '/error',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    name: 'ErrorPages',
-    meta: {
-      title: 'Error Pages',
-      icon: '404'
-    },
-    children: [
-      {
-        path: '401',
-        component: 'views/error-page/401',
-        name: 'Page401',
-        meta: { title: 'Page 401', noCache: true }
-      },
-      {
-        path: '404',
-        component: 'views/error-page/404',
-        name: 'Page404',
-        meta: { title: 'Page 404', noCache: true }
-      }
-    ]
-  },
-
-  {
-    path: '/error-log',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    children: [
-      {
-        path: 'log',
-        component: 'views/error-log/index',
-        name: 'ErrorLog',
-        meta: { title: 'Error Log', icon: 'bug' }
-      }
-    ]
-  },
-
-  {
-    path: '/excel',
-    component: 'layout/Layout',
-    redirect: '/excel/export-excel',
-    name: 'Excel',
-    meta: {
-      title: 'Excel',
-      icon: 'excel'
-    },
-    children: [
-      {
-        path: 'export-excel',
-        component: 'views/excel/export-excel',
-        name: 'ExportExcel',
-        meta: { title: 'Export Excel' }
-      },
-      {
-        path: 'export-selected-excel',
-        component: 'views/excel/select-excel',
-        name: 'SelectExcel',
-        meta: { title: 'Select Excel' }
-      },
-      {
-        path: 'export-merge-header',
-        component: 'views/excel/merge-header',
-        name: 'MergeHeader',
-        meta: { title: 'Merge Header' }
-      },
-      {
-        path: 'upload-excel',
-        component: 'views/excel/upload-excel',
-        name: 'UploadExcel',
-        meta: { title: 'Upload Excel' }
-      }
-    ]
-  },
-
-  {
-    path: '/zip',
-    component: 'layout/Layout',
-    redirect: '/zip/download',
-    alwaysShow: true,
-    meta: { title: 'Zip', icon: 'zip' },
-    children: [
-      {
-        path: 'download',
-        component: 'views/zip/index',
-        name: 'ExportZip',
-        meta: { title: 'Export Zip' }
-      }
-    ]
-  },
-
-  {
-    path: '/pdf',
-    component: 'layout/Layout',
-    redirect: '/pdf/index',
-    children: [
-      {
-        path: 'index',
-        component: 'views/pdf/index',
-        name: 'PDF',
-        meta: { title: 'PDF', icon: 'pdf' }
-      }
-    ]
-  },
-  {
-    path: '/pdf/download',
-    component: 'views/pdf/download',
-    hidden: true
-  },
-
-  {
-    path: '/theme',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    children: [
-      {
-        path: 'index',
-        component: 'views/theme/index',
-        name: 'Theme',
-        meta: { title: 'Theme', icon: 'theme' }
-      }
-    ]
-  },
-
-  {
-    path: '/clipboard',
-    component: 'layout/Layout',
-    redirect: 'noRedirect',
-    children: [
-      {
-        path: 'index',
-        component: 'views/clipboard/index',
-        name: 'ClipboardDemo',
-        meta: { title: 'Clipboard Demo', icon: 'clipboard' }
-      }
-    ]
-  },
-
-  {
-    path: '/i18n',
-    component: 'layout/Layout',
-    children: [
-      {
-        path: 'index',
-        component: 'views/i18n-demo/index',
-        name: 'I18n',
-        meta: { title: 'I18n', icon: 'international' }
-      }
-    ]
-  },
-
-  {
-    path: 'external-link',
-    component: 'layout/Layout',
-    children: [
-      {
-        path: 'https://github.com/PanJiaChen/vue-element-admin',
-        meta: { title: 'External Link', icon: 'link' }
-      }
-    ]
-  },
-
-  { path: '*', redirect: '/404', hidden: true }
-]
-
-module.exports = {
-  constantRoutes,
-  asyncRoutes
-}

+ 0 - 84
mock/user.js

@@ -1,84 +0,0 @@
-
-const tokens = {
-  admin: {
-    token: 'admin-token'
-  },
-  editor: {
-    token: 'editor-token'
-  }
-}
-
-const users = {
-  'admin-token': {
-    roles: ['admin'],
-    introduction: 'I am a super administrator',
-    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
-    name: 'Super Admin'
-  },
-  'editor-token': {
-    roles: ['editor'],
-    introduction: 'I am an editor',
-    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
-    name: 'Normal Editor'
-  }
-}
-
-module.exports = [
-  // user login
-  {
-    url: '/vue-element-admin/user/login',
-    type: 'post',
-    response: config => {
-      const { username } = config.body
-      const token = tokens[username]
-
-      // mock error
-      if (!token) {
-        return {
-          code: 60204,
-          message: 'Account and password are incorrect.'
-        }
-      }
-
-      return {
-        code: 20000,
-        data: token
-      }
-    }
-  },
-
-  // get user info
-  {
-    url: '/vue-element-admin/user/info\.*',
-    type: 'get',
-    response: config => {
-      const { token } = config.query
-      const info = users[token]
-
-      // mock error
-      if (!info) {
-        return {
-          code: 50008,
-          message: 'Login failed, unable to get user details.'
-        }
-      }
-
-      return {
-        code: 20000,
-        data: info
-      }
-    }
-  },
-
-  // user logout
-  {
-    url: '/vue-element-admin/user/logout',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        data: 'success'
-      }
-    }
-  }
-]

+ 0 - 48
mock/utils.js

@@ -1,48 +0,0 @@
-/**
- * @param {string} url
- * @returns {Object}
- */
-function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
-  if (!search) {
-    return {}
-  }
-  const obj = {}
-  const searchArr = search.split('&')
-  searchArr.forEach(v => {
-    const index = v.indexOf('=')
-    if (index !== -1) {
-      const name = v.substring(0, index)
-      const val = v.substring(index + 1, v.length)
-      obj[name] = val
-    }
-  })
-  return obj
-}
-
-/**
- * This is just a simple version of deep copy
- * Has a lot of edge cases bug
- * If you want to use a perfect deep copy, use lodash's _.cloneDeep
- * @param {Object} source
- * @returns {Object}
- */
-function deepClone(source) {
-  if (!source && typeof source !== 'object') {
-    throw new Error('error arguments', 'deepClone')
-  }
-  const targetObj = source.constructor === Array ? [] : {}
-  Object.keys(source).forEach(keys => {
-    if (source[keys] && typeof source[keys] === 'object') {
-      targetObj[keys] = deepClone(source[keys])
-    } else {
-      targetObj[keys] = source[keys]
-    }
-  })
-  return targetObj
-}
-
-module.exports = {
-  param2Obj,
-  deepClone
-}

+ 0 - 42
src/api/article.js

@@ -1,42 +0,0 @@
-import request from '@/utils/request'
-
-export function fetchList(query) {
-  return request({
-    url: '/vue-element-admin/article/list',
-    method: 'get',
-    params: query
-  })
-}
-
-export function fetchArticle(id) {
-  return request({
-    url: '/vue-element-admin/article/detail',
-    method: 'get',
-    params: { id }
-  })
-}
-
-export function fetchPv(pv) {
-  return request({
-    url: '/vue-element-admin/article/pv',
-    method: 'get',
-    params: { pv }
-  })
-}
-
-export function createArticle(data) {
-  return request({
-    url: '/vue-element-admin/article/create',
-    method: 'post',
-    data
-  })
-}
-
-export function updateArticle(data) {
-  return request({
-    url: '/vue-element-admin/article/update',
-    method: 'post',
-    data
-  })
-}
-

+ 0 - 8
src/api/qiniu.js

@@ -1,8 +0,0 @@
-import request from '@/utils/request'
-
-export function getToken() {
-  return request({
-    url: '/qiniu/upload/token', // 假地址 自行替换
-    method: 'get'
-  })
-}

+ 0 - 17
src/api/remote-search.js

@@ -1,17 +0,0 @@
-import request from '@/utils/request'
-
-export function searchUser(name) {
-  return request({
-    url: '/vue-element-admin/search/user',
-    method: 'get',
-    params: { name }
-  })
-}
-
-export function transactionList(query) {
-  return request({
-    url: '/vue-element-admin/transaction/list',
-    method: 'get',
-    params: query
-  })
-}

+ 0 - 38
src/api/role.js

@@ -1,38 +0,0 @@
-import request from '@/utils/request'
-
-export function getRoutes() {
-  return request({
-    url: '/vue-element-admin/routes',
-    method: 'get'
-  })
-}
-
-export function getRoles() {
-  return request({
-    url: '/vue-element-admin/roles',
-    method: 'get'
-  })
-}
-
-export function addRole(data) {
-  return request({
-    url: '/vue-element-admin/role',
-    method: 'post',
-    data
-  })
-}
-
-export function updateRole(id, data) {
-  return request({
-    url: `/vue-element-admin/role/${id}`,
-    method: 'put',
-    data
-  })
-}
-
-export function deleteRole(id) {
-  return request({
-    url: `/vue-element-admin/role/${id}`,
-    method: 'delete'
-  })
-}

+ 0 - 145
src/components/RightPanel/index.vue

@@ -1,145 +0,0 @@
-<template>
-  <div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
-    <div class="rightPanel-background" />
-    <div class="rightPanel">
-      <div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
-        <i :class="show?'el-icon-close':'el-icon-setting'" />
-      </div>
-      <div class="rightPanel-items">
-        <slot />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { addClass, removeClass } from '@/utils'
-
-export default {
-  name: 'RightPanel',
-  props: {
-    clickNotClose: {
-      default: false,
-      type: Boolean
-    },
-    buttonTop: {
-      default: 250,
-      type: Number
-    }
-  },
-  data() {
-    return {
-      show: false
-    }
-  },
-  computed: {
-    theme() {
-      return this.$store.state.settings.theme
-    }
-  },
-  watch: {
-    show(value) {
-      if (value && !this.clickNotClose) {
-        this.addEventClick()
-      }
-      if (value) {
-        addClass(document.body, 'showRightPanel')
-      } else {
-        removeClass(document.body, 'showRightPanel')
-      }
-    }
-  },
-  mounted() {
-    this.insertToBody()
-  },
-  beforeDestroy() {
-    const elx = this.$refs.rightPanel
-    elx.remove()
-  },
-  methods: {
-    addEventClick() {
-      window.addEventListener('click', this.closeSidebar)
-    },
-    closeSidebar(evt) {
-      const parent = evt.target.closest('.rightPanel')
-      if (!parent) {
-        this.show = false
-        window.removeEventListener('click', this.closeSidebar)
-      }
-    },
-    insertToBody() {
-      const elx = this.$refs.rightPanel
-      const body = document.querySelector('body')
-      body.insertBefore(elx, body.firstChild)
-    }
-  }
-}
-</script>
-
-<style>
-.showRightPanel {
-  overflow: hidden;
-  position: relative;
-  width: calc(100% - 15px);
-}
-</style>
-
-<style lang="scss" scoped>
-.rightPanel-background {
-  position: fixed;
-  top: 0;
-  left: 0;
-  opacity: 0;
-  transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
-  background: rgba(0, 0, 0, .2);
-  z-index: -1;
-}
-
-.rightPanel {
-  width: 100%;
-  max-width: 260px;
-  height: 100vh;
-  position: fixed;
-  top: 0;
-  right: 0;
-  box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
-  transition: all .25s cubic-bezier(.7, .3, .1, 1);
-  transform: translate(100%);
-  background: #fff;
-  z-index: 40000;
-}
-
-.show {
-  transition: all .3s cubic-bezier(.7, .3, .1, 1);
-
-  .rightPanel-background {
-    z-index: 20000;
-    opacity: 1;
-    width: 100%;
-    height: 100%;
-  }
-
-  .rightPanel {
-    transform: translate(0);
-  }
-}
-
-.handle-button {
-  width: 48px;
-  height: 48px;
-  position: absolute;
-  left: -48px;
-  text-align: center;
-  font-size: 24px;
-  border-radius: 6px 0 0 6px !important;
-  z-index: 0;
-  pointer-events: auto;
-  cursor: pointer;
-  color: #fff;
-  line-height: 48px;
-  i {
-    font-size: 24px;
-    line-height: 48px;
-  }
-}
-</style>

+ 0 - 108
src/layout/components/Settings/index.vue

@@ -1,108 +0,0 @@
-<template>
-  <div class="drawer-container">
-    <div>
-      <h3 class="drawer-title">Page style setting</h3>
-
-      <div class="drawer-item">
-        <span>Theme Color</span>
-        <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
-      </div>
-
-      <div class="drawer-item">
-        <span>Open Tags-View</span>
-        <el-switch v-model="tagsView" class="drawer-switch" />
-      </div>
-
-      <div class="drawer-item">
-        <span>Fixed Header</span>
-        <el-switch v-model="fixedHeader" class="drawer-switch" />
-      </div>
-
-      <div class="drawer-item">
-        <span>Sidebar Logo</span>
-        <el-switch v-model="sidebarLogo" class="drawer-switch" />
-      </div>
-
-    </div>
-  </div>
-</template>
-
-<script>
-import ThemePicker from '@/components/ThemePicker'
-
-export default {
-  components: { ThemePicker },
-  data() {
-    return {}
-  },
-  computed: {
-    fixedHeader: {
-      get() {
-        return this.$store.state.settings.fixedHeader
-      },
-      set(val) {
-        this.$store.dispatch('settings/changeSetting', {
-          key: 'fixedHeader',
-          value: val
-        })
-      }
-    },
-    tagsView: {
-      get() {
-        return this.$store.state.settings.tagsView
-      },
-      set(val) {
-        this.$store.dispatch('settings/changeSetting', {
-          key: 'tagsView',
-          value: val
-        })
-      }
-    },
-    sidebarLogo: {
-      get() {
-        return this.$store.state.settings.sidebarLogo
-      },
-      set(val) {
-        this.$store.dispatch('settings/changeSetting', {
-          key: 'sidebarLogo',
-          value: val
-        })
-      }
-    }
-  },
-  methods: {
-    themeChange(val) {
-      this.$store.dispatch('settings/changeSetting', {
-        key: 'theme',
-        value: val
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.drawer-container {
-  padding: 24px;
-  font-size: 14px;
-  line-height: 1.5;
-  word-wrap: break-word;
-
-  .drawer-title {
-    margin-bottom: 12px;
-    color: rgba(0, 0, 0, .85);
-    font-size: 14px;
-    line-height: 22px;
-  }
-
-  .drawer-item {
-    color: rgba(0, 0, 0, .65);
-    font-size: 14px;
-    padding: 12px 0;
-  }
-
-  .drawer-switch {
-    float: right
-  }
-}
-</style>

+ 47 - 49
src/layout/index.vue

@@ -1,23 +1,23 @@
 <template>
   <div :class="classObj" class="app-wrapper">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+    <div
+      v-if="device === 'mobile' && sidebar.opened"
+      class="drawer-bg"
+      @click="handleClickOutside"
+    />
     <sidebar class="sidebar-container" />
-    <div :class="{hasTagsView:needTagsView}" class="main-container">
-      <div :class="{'fixed-header':fixedHeader}">
+    <div :class="{ hasTagsView: needTagsView }" class="main-container">
+      <div :class="{ 'fixed-header': fixedHeader }">
         <navbar />
         <tags-view v-if="needTagsView" />
       </div>
       <app-main />
-      <right-panel v-if="showSettings">
-        <settings />
-      </right-panel>
     </div>
   </div>
 </template>
 
 <script>
-import RightPanel from '@/components/RightPanel'
-import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
+import { AppMain, Navbar, Sidebar, TagsView } from './components'
 import ResizeMixin from './mixin/ResizeHandler'
 import { mapState } from 'vuex'
 
@@ -26,19 +26,17 @@ export default {
   components: {
     AppMain,
     Navbar,
-    RightPanel,
-    Settings,
     Sidebar,
     TagsView
   },
   mixins: [ResizeMixin],
   computed: {
     ...mapState({
-      sidebar: state => state.app.sidebar,
-      device: state => state.app.device,
-      showSettings: state => state.settings.showSettings,
-      needTagsView: state => state.settings.tagsView,
-      fixedHeader: state => state.settings.fixedHeader
+      sidebar: (state) => state.app.sidebar,
+      device: (state) => state.app.device,
+      showSettings: (state) => state.settings.showSettings,
+      needTagsView: (state) => state.settings.tagsView,
+      fixedHeader: (state) => state.settings.fixedHeader
     }),
     classObj() {
       return {
@@ -58,45 +56,45 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
+@import "~@/styles/mixin.scss";
+@import "~@/styles/variables.scss";
 
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
+.app-wrapper {
+  @include clearfix;
+  position: relative;
+  height: 100%;
+  width: 100%;
 
-    &.mobile.openSidebar {
-      position: fixed;
-      top: 0;
-    }
-  }
-
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
-
-  .fixed-header {
+  &.mobile.openSidebar {
     position: fixed;
     top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$sideBarWidth});
-    transition: width 0.28s;
   }
+}
 
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
-  }
+.drawer-bg {
+  background: #000;
+  opacity: 0.3;
+  width: 100%;
+  top: 0;
+  height: 100%;
+  position: absolute;
+  z-index: 999;
+}
 
-  .mobile .fixed-header {
-    width: 100%;
-  }
+.fixed-header {
+  position: fixed;
+  top: 0;
+  right: 0;
+  z-index: 9;
+  width: calc(100% - #{$sideBarWidth});
+  transition: width 0.28s;
+}
+
+.hideSidebar .fixed-header {
+  width: calc(100% - 54px);
+}
+
+.mobile .fixed-header {
+  width: 100%;
+}
 </style>

+ 0 - 275
src/router/index.js

@@ -6,13 +6,6 @@ Vue.use(Router)
 /* Layout */
 import Layout from '@/layout'
 
-/* Router Modules */
-import componentsRouter from './modules/components'
-import chartsRouter from './modules/charts'
-import tableRouter from './modules/table'
-import nestedRouter from './modules/nested'
-
-
 export const constantRoutes = [
   {
     path: '/redirect',
@@ -161,19 +154,6 @@ export const constantRoutes = [
       }
     ]
   },
-  // {
-  //   path: '/management',
-  //   component: Layout,
-  //   redirect: '/management/index',
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/management/index'),
-  //       name: 'management',
-  //       meta: { title: '大门管理', icon: 'lock', noCache: true }
-  //     }
-  //   ]
-  // },
   {
     path: '/profile',
     component: Layout,
@@ -195,261 +175,6 @@ export const constantRoutes = [
  * the routes that need to be dynamically loaded based on user roles
  */
 export const asyncRoutes = [
-
-  // {
-  //   path: '/permission',
-  //   component: Layout,
-  //   redirect: '/permission/page',
-  //   alwaysShow: true, // will always show the root menu
-  //   name: 'Permission',
-  //   meta: {
-  //     title: 'Permission',
-  //     icon: 'lock',
-  //     roles: ['admin', 'editor'] // you can set roles in root nav
-  //   },
-  //   children: [
-  //     {
-  //       path: 'page',
-  //       component: () => import('@/views/permission/page'),
-  //       name: 'PagePermission',
-  //       meta: {
-  //         title: 'Page Permission',
-  //         roles: ['admin'] // or you can only set roles in sub nav
-  //       }
-  //     },
-  //     {
-  //       path: 'directive',
-  //       component: () => import('@/views/permission/directive'),
-  //       name: 'DirectivePermission',
-  //       meta: {
-  //         title: 'Directive Permission'
-  //         // if do not set roles, means: this page does not require permission
-  //       }
-  //     },
-  //     {
-  //       path: 'role',
-  //       component: () => import('@/views/permission/role'),
-  //       name: 'RolePermission',
-  //       meta: {
-  //         title: 'Role Permission',
-  //         roles: ['admin']
-  //       }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/icon',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/icons/index'),
-  //       name: 'Icons',
-  //       meta: { title: 'Icons', icon: 'icon', noCache: true }
-  //     }
-  //   ]
-  // },
-
-  /** when your routing map is too long, you can split it into small modules **/
-  // componentsRouter,
-  // chartsRouter,
-  // nestedRouter,
-  // tableRouter,
-
-  // {
-  //   path: '/example',
-  //   component: Layout,
-  //   redirect: '/example/list',
-  //   name: 'Example',
-  //   meta: {
-  //     title: 'Example',
-  //     icon: 'el-icon-s-help'
-  //   },
-  //   children: [
-  //     {
-  //       path: 'create',
-  //       component: () => import('@/views/example/create'),
-  //       name: 'CreateArticle',
-  //       meta: { title: 'Create Article', icon: 'edit' }
-  //     },
-  //     {
-  //       path: 'edit/:id(\\d+)',
-  //       component: () => import('@/views/example/edit'),
-  //       name: 'EditArticle',
-  //       meta: { title: 'Edit Article', noCache: true, activeMenu: '/example/list' },
-  //       hidden: true
-  //     },
-  //     {
-  //       path: 'list',
-  //       component: () => import('@/views/example/list'),
-  //       name: 'ArticleList',
-  //       meta: { title: 'Article List', icon: 'list' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/tab',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/tab/index'),
-  //       name: 'Tab',
-  //       meta: { title: 'Tab', icon: 'tab' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/error',
-  //   component: Layout,
-  //   redirect: 'noRedirect',
-  //   name: 'ErrorPages',
-  //   meta: {
-  //     title: 'Error Pages',
-  //     icon: '404'
-  //   },
-  //   children: [
-  //     {
-  //       path: '401',
-  //       component: () => import('@/views/error-page/401'),
-  //       name: 'Page401',
-  //       meta: { title: '401', noCache: true }
-  //     },
-  //     {
-  //       path: '404',
-  //       component: () => import('@/views/error-page/404'),
-  //       name: 'Page404',
-  //       meta: { title: '404', noCache: true }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/error-log',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'log',
-  //       component: () => import('@/views/error-log/index'),
-  //       name: 'ErrorLog',
-  //       meta: { title: 'Error Log', icon: 'bug' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/excel',
-  //   component: Layout,
-  //   redirect: '/excel/export-excel',
-  //   name: 'Excel',
-  //   meta: {
-  //     title: 'Excel',
-  //     icon: 'excel'
-  //   },
-  //   children: [
-  //     {
-  //       path: 'export-excel',
-  //       component: () => import('@/views/excel/export-excel'),
-  //       name: 'ExportExcel',
-  //       meta: { title: 'Export Excel' }
-  //     },
-  //     {
-  //       path: 'export-selected-excel',
-  //       component: () => import('@/views/excel/select-excel'),
-  //       name: 'SelectExcel',
-  //       meta: { title: 'Export Selected' }
-  //     },
-  //     {
-  //       path: 'export-merge-header',
-  //       component: () => import('@/views/excel/merge-header'),
-  //       name: 'MergeHeader',
-  //       meta: { title: 'Merge Header' }
-  //     },
-  //     {
-  //       path: 'upload-excel',
-  //       component: () => import('@/views/excel/upload-excel'),
-  //       name: 'UploadExcel',
-  //       meta: { title: 'Upload Excel' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/zip',
-  //   component: Layout,
-  //   redirect: '/zip/download',
-  //   alwaysShow: true,
-  //   name: 'Zip',
-  //   meta: { title: 'Zip', icon: 'zip' },
-  //   children: [
-  //     {
-  //       path: 'download',
-  //       component: () => import('@/views/zip/index'),
-  //       name: 'ExportZip',
-  //       meta: { title: 'Export Zip' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/pdf',
-  //   component: Layout,
-  //   redirect: '/pdf/index',
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/pdf/index'),
-  //       name: 'PDF',
-  //       meta: { title: 'PDF', icon: 'pdf' }
-  //     }
-  //   ]
-  // },
-  // {
-  //   path: '/pdf/download',
-  //   component: () => import('@/views/pdf/download'),
-  //   hidden: true
-  // },
-
-  // {
-  //   path: '/theme',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/theme/index'),
-  //       name: 'Theme',
-  //       meta: { title: 'Theme', icon: 'theme' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/clipboard',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       component: () => import('@/views/clipboard/index'),
-  //       name: 'ClipboardDemo',
-  //       meta: { title: 'Clipboard', icon: 'clipboard' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: 'external-link',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'https://github.com/PanJiaChen/vue-element-admin',
-  //       meta: { title: 'External Link', icon: 'link' }
-  //     }
-  //   ]
-  // },
-
   // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404', hidden: true }
 ]

+ 0 - 36
src/router/modules/charts.js

@@ -1,36 +0,0 @@
-/** When your routing table is too long, you can split it into small modules**/
-
-import Layout from '@/layout'
-
-const chartsRouter = {
-  path: '/charts',
-  component: Layout,
-  redirect: 'noRedirect',
-  name: 'Charts',
-  meta: {
-    title: 'Charts',
-    icon: 'chart'
-  },
-  children: [
-    {
-      path: 'keyboard',
-      component: () => import('@/views/charts/keyboard'),
-      name: 'KeyboardChart',
-      meta: { title: 'Keyboard Chart', noCache: true }
-    },
-    {
-      path: 'line',
-      component: () => import('@/views/charts/line'),
-      name: 'LineChart',
-      meta: { title: 'Line Chart', noCache: true }
-    },
-    {
-      path: 'mix-chart',
-      component: () => import('@/views/charts/mix-chart'),
-      name: 'MixChart',
-      meta: { title: 'Mix Chart', noCache: true }
-    }
-  ]
-}
-
-export default chartsRouter

+ 0 - 102
src/router/modules/components.js

@@ -1,102 +0,0 @@
-/** When your routing table is too long, you can split it into small modules **/
-
-import Layout from '@/layout'
-
-const componentsRouter = {
-  path: '/components',
-  component: Layout,
-  redirect: 'noRedirect',
-  name: 'ComponentDemo',
-  meta: {
-    title: 'Components',
-    icon: 'component'
-  },
-  children: [
-    {
-      path: 'tinymce',
-      component: () => import('@/views/components-demo/tinymce'),
-      name: 'TinymceDemo',
-      meta: { title: 'Tinymce' }
-    },
-    {
-      path: 'markdown',
-      component: () => import('@/views/components-demo/markdown'),
-      name: 'MarkdownDemo',
-      meta: { title: 'Markdown' }
-    },
-    {
-      path: 'json-editor',
-      component: () => import('@/views/components-demo/json-editor'),
-      name: 'JsonEditorDemo',
-      meta: { title: 'JSON Editor' }
-    },
-    {
-      path: 'split-pane',
-      component: () => import('@/views/components-demo/split-pane'),
-      name: 'SplitpaneDemo',
-      meta: { title: 'SplitPane' }
-    },
-    {
-      path: 'avatar-upload',
-      component: () => import('@/views/components-demo/avatar-upload'),
-      name: 'AvatarUploadDemo',
-      meta: { title: 'Upload' }
-    },
-    {
-      path: 'dropzone',
-      component: () => import('@/views/components-demo/dropzone'),
-      name: 'DropzoneDemo',
-      meta: { title: 'Dropzone' }
-    },
-    {
-      path: 'sticky',
-      component: () => import('@/views/components-demo/sticky'),
-      name: 'StickyDemo',
-      meta: { title: 'Sticky' }
-    },
-    {
-      path: 'count-to',
-      component: () => import('@/views/components-demo/count-to'),
-      name: 'CountToDemo',
-      meta: { title: 'Count To' }
-    },
-    {
-      path: 'mixin',
-      component: () => import('@/views/components-demo/mixin'),
-      name: 'ComponentMixinDemo',
-      meta: { title: 'Component Mixin' }
-    },
-    {
-      path: 'back-to-top',
-      component: () => import('@/views/components-demo/back-to-top'),
-      name: 'BackToTopDemo',
-      meta: { title: 'Back To Top' }
-    },
-    {
-      path: 'drag-dialog',
-      component: () => import('@/views/components-demo/drag-dialog'),
-      name: 'DragDialogDemo',
-      meta: { title: 'Drag Dialog' }
-    },
-    {
-      path: 'drag-select',
-      component: () => import('@/views/components-demo/drag-select'),
-      name: 'DragSelectDemo',
-      meta: { title: 'Drag Select' }
-    },
-    {
-      path: 'dnd-list',
-      component: () => import('@/views/components-demo/dnd-list'),
-      name: 'DndListDemo',
-      meta: { title: 'Dnd List' }
-    },
-    {
-      path: 'drag-kanban',
-      component: () => import('@/views/components-demo/drag-kanban'),
-      name: 'DragKanbanDemo',
-      meta: { title: 'Drag Kanban' }
-    }
-  ]
-}
-
-export default componentsRouter

+ 0 - 66
src/router/modules/nested.js

@@ -1,66 +0,0 @@
-/** When your routing table is too long, you can split it into small modules **/
-
-import Layout from '@/layout'
-
-const nestedRouter = {
-  path: '/nested',
-  component: Layout,
-  redirect: '/nested/menu1/menu1-1',
-  name: 'Nested',
-  meta: {
-    title: 'Nested Routes',
-    icon: 'nested'
-  },
-  children: [
-    {
-      path: 'menu1',
-      component: () => import('@/views/nested/menu1/index'), // Parent router-view
-      name: 'Menu1',
-      meta: { title: 'Menu 1' },
-      redirect: '/nested/menu1/menu1-1',
-      children: [
-        {
-          path: 'menu1-1',
-          component: () => import('@/views/nested/menu1/menu1-1'),
-          name: 'Menu1-1',
-          meta: { title: 'Menu 1-1' }
-        },
-        {
-          path: 'menu1-2',
-          component: () => import('@/views/nested/menu1/menu1-2'),
-          name: 'Menu1-2',
-          redirect: '/nested/menu1/menu1-2/menu1-2-1',
-          meta: { title: 'Menu 1-2' },
-          children: [
-            {
-              path: 'menu1-2-1',
-              component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
-              name: 'Menu1-2-1',
-              meta: { title: 'Menu 1-2-1' }
-            },
-            {
-              path: 'menu1-2-2',
-              component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
-              name: 'Menu1-2-2',
-              meta: { title: 'Menu 1-2-2' }
-            }
-          ]
-        },
-        {
-          path: 'menu1-3',
-          component: () => import('@/views/nested/menu1/menu1-3'),
-          name: 'Menu1-3',
-          meta: { title: 'Menu 1-3' }
-        }
-      ]
-    },
-    {
-      path: 'menu2',
-      name: 'Menu2',
-      component: () => import('@/views/nested/menu2/index'),
-      meta: { title: 'Menu 2' }
-    }
-  ]
-}
-
-export default nestedRouter

+ 0 - 41
src/router/modules/table.js

@@ -1,41 +0,0 @@
-/** When your routing table is too long, you can split it into small modules **/
-
-import Layout from '@/layout'
-
-const tableRouter = {
-  path: '/table',
-  component: Layout,
-  redirect: '/table/complex-table',
-  name: 'Table',
-  meta: {
-    title: 'Table',
-    icon: 'table'
-  },
-  children: [
-    {
-      path: 'dynamic-table',
-      component: () => import('@/views/table/dynamic-table/index'),
-      name: 'DynamicTable',
-      meta: { title: 'Dynamic Table' }
-    },
-    {
-      path: 'drag-table',
-      component: () => import('@/views/table/drag-table'),
-      name: 'DragTable',
-      meta: { title: 'Drag Table' }
-    },
-    {
-      path: 'inline-edit-table',
-      component: () => import('@/views/table/inline-edit-table'),
-      name: 'InlineEditTable',
-      meta: { title: 'Inline Edit' }
-    },
-    {
-      path: 'complex-table',
-      component: () => import('@/views/table/complex-table'),
-      name: 'ComplexTable',
-      meta: { title: 'Complex Table' }
-    }
-  ]
-}
-export default tableRouter

+ 0 - 23
src/views/charts/keyboard.vue

@@ -1,23 +0,0 @@
-<template>
-  <div class="chart-container">
-    <chart height="100%" width="100%" />
-  </div>
-</template>
-
-<script>
-import Chart from '@/components/Charts/Keyboard'
-
-export default {
-  name: 'KeyboardChart',
-  components: { Chart }
-}
-</script>
-
-<style scoped>
-.chart-container{
-  position: relative;
-  width: 100%;
-  height: calc(100vh - 84px);
-}
-</style>
-

+ 0 - 23
src/views/charts/line.vue

@@ -1,23 +0,0 @@
-<template>
-  <div class="chart-container">
-    <chart height="100%" width="100%" />
-  </div>
-</template>
-
-<script>
-import Chart from '@/components/Charts/LineMarker'
-
-export default {
-  name: 'LineChart',
-  components: { Chart }
-}
-</script>
-
-<style scoped>
-.chart-container{
-  position: relative;
-  width: 100%;
-  height: calc(100vh - 84px);
-}
-</style>
-

+ 0 - 23
src/views/charts/mix-chart.vue

@@ -1,23 +0,0 @@
-<template>
-  <div class="chart-container">
-    <chart height="100%" width="100%" />
-  </div>
-</template>
-
-<script>
-import Chart from '@/components/Charts/MixChart'
-
-export default {
-  name: 'MixChart',
-  components: { Chart }
-}
-</script>
-
-<style scoped>
-.chart-container{
-  position: relative;
-  width: 100%;
-  height: calc(100vh - 84px);
-}
-</style>
-

+ 0 - 61
src/views/components-demo/avatar-upload.vue

@@ -1,61 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>This is based on
-      <a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
-      Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.
-    </aside>
-
-    <pan-thumb :image="image" />
-
-    <el-button type="primary" icon="el-icon-upload" style="position: absolute;bottom: 15px;margin-left: 40px;" @click="imagecropperShow=true">
-      Change Avatar
-    </el-button>
-
-    <image-cropper
-      v-show="imagecropperShow"
-      :key="imagecropperKey"
-      :width="300"
-      :height="300"
-      url="https://httpbin.org/post"
-      lang-type="en"
-      @close="close"
-      @crop-upload-success="cropSuccess"
-    />
-  </div>
-</template>
-
-<script>
-import ImageCropper from '@/components/ImageCropper'
-import PanThumb from '@/components/PanThumb'
-
-export default {
-  name: 'AvatarUploadDemo',
-  components: { ImageCropper, PanThumb },
-  data() {
-    return {
-      imagecropperShow: false,
-      imagecropperKey: 0,
-      image: 'https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191'
-    }
-  },
-  methods: {
-    cropSuccess(resData) {
-      this.imagecropperShow = false
-      this.imagecropperKey = this.imagecropperKey + 1
-      this.image = resData.files.avatar
-    },
-    close() {
-      this.imagecropperShow = false
-    }
-  }
-}
-</script>
-
-<style scoped>
-  .avatar{
-    width: 200px;
-    height: 200px;
-    border-radius: 50%;
-  }
-</style>
-

+ 0 - 154
src/views/components-demo/back-to-top.vue

@@ -1,154 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>
-      When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner
-    </aside>
-    <aside>
-      You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally
-    </aside>
-    <div class="placeholder-container">
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-    </div>
-    <!-- you can add element-ui's tooltip -->
-    <el-tooltip placement="top" content="tooltip">
-      <back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" />
-    </el-tooltip>
-  </div>
-</template>
-
-<script>
-import BackToTop from '@/components/BackToTop'
-
-export default {
-  name: 'BackToTopDemo',
-  components: { BackToTop },
-  data() {
-    return {
-      // customizable button style, show/hide critical point, return position
-      myBackToTopStyle: {
-        right: '50px',
-        bottom: '50px',
-        width: '40px',
-        height: '40px',
-        'border-radius': '4px',
-        'line-height': '45px', // 请保持与高度一致以垂直居中 Please keep consistent with height to center vertically
-        background: '#e7eaf1'// 按钮的背景颜色 The background color of the button
-      }
-    }
-  }
-}
-</script>
-
-<style scoped>
-.placeholder-container div {
-  margin: 10px;
-}
-</style>

+ 0 - 218
src/views/components-demo/count-to.vue

@@ -1,218 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>
-      <a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a>
-    </aside>
-    <count-to
-      ref="example"
-      :start-val="_startVal"
-      :end-val="_endVal"
-      :duration="_duration"
-      :decimals="_decimals"
-      :separator="_separator"
-      :prefix="_prefix"
-      :suffix="_suffix"
-      :autoplay="false"
-      class="example"
-    />
-    <div style="margin-left: 25%;margin-top: 40px;">
-      <label class="label" for="startValInput">startVal:
-        <input v-model.number="setStartVal" type="number" name="startValInput">
-      </label>
-      <label class="label" for="endValInput">endVal:
-        <input v-model.number="setEndVal" type="number" name="endVaInput">
-      </label>
-      <label class="label" for="durationInput">duration:
-        <input v-model.number="setDuration" type="number" name="durationInput">
-      </label>
-      <div class="startBtn example-btn" @click="start">
-        Start
-      </div>
-      <div class="pause-resume-btn example-btn" @click="pauseResume">
-        pause/resume
-      </div>
-      <br>
-      <label class="label" for="decimalsInput">decimals:
-        <input v-model.number="setDecimals" type="number" name="decimalsInput">
-      </label>
-      <label class="label" for="separatorInput">separator:
-        <input v-model="setSeparator" name="separatorInput">
-      </label>
-      <label class="label" for="prefixInput">prefix:
-        <input v-model="setPrefix" name="prefixInput">
-      </label>
-      <label class="label" for="suffixInput">suffix:
-        <input v-model="setSuffix" name="suffixInput">
-      </label>
-    </div>
-    <aside>&lt;count-to :start-val=&#x27;{{ _startVal }}&#x27; :end-val=&#x27;{{ _endVal }}&#x27; :duration=&#x27;{{ _duration }}&#x27;
-      :decimals=&#x27;{{ _decimals }}&#x27; :separator=&#x27;{{ _separator }}&#x27; :prefix=&#x27;{{ _prefix }}&#x27; :suffix=&#x27;{{ _suffix }}&#x27;
-      :autoplay=false&gt;</aside>
-  </div>
-</template>
-
-<script>
-import countTo from 'vue-count-to'
-
-export default {
-  name: 'CountToDemo',
-  components: { countTo },
-  data() {
-    return {
-      setStartVal: 0,
-      setEndVal: 2017,
-      setDuration: 4000,
-      setDecimals: 0,
-      setSeparator: ',',
-      setSuffix: ' rmb',
-      setPrefix: '¥ '
-    }
-  },
-  computed: {
-    _startVal() {
-      if (this.setStartVal) {
-        return this.setStartVal
-      } else {
-        return 0
-      }
-    },
-    _endVal() {
-      if (this.setEndVal) {
-        return this.setEndVal
-      } else {
-        return 0
-      }
-    },
-    _duration() {
-      if (this.setDuration) {
-        return this.setDuration
-      } else {
-        return 100
-      }
-    },
-    _decimals() {
-      if (this.setDecimals) {
-        if (this.setDecimals < 0 || this.setDecimals > 20) {
-          alert('digits argument must be between 0 and 20')
-          return 0
-        }
-        return this.setDecimals
-      } else {
-        return 0
-      }
-    },
-    _separator() {
-      return this.setSeparator
-    },
-    _suffix() {
-      return this.setSuffix
-    },
-    _prefix() {
-      return this.setPrefix
-    }
-  },
-  methods: {
-    start() {
-      this.$refs.example.start()
-    },
-    pauseResume() {
-      this.$refs.example.pauseResume()
-    }
-  }
-}
-</script>
-
-<style scoped>
-.example-btn {
-  display: inline-block;
-  margin-bottom: 0;
-  font-weight: 500;
-  text-align: center;
-  -ms-touch-action: manipulation;
-  touch-action: manipulation;
-  cursor: pointer;
-  background-image: none;
-  border: 1px solid transparent;
-  white-space: nowrap;
-  line-height: 1.5;
-  padding: 4px 15px;
-  font-size: 12px;
-  border-radius: 4px;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  -webkit-transition: all .3s cubic-bezier(.645, .045, .355, 1);
-  transition: all .3s cubic-bezier(.645, .045, .355, 1);
-  position: relative;
-  color: rgba(0, 0, 0, .65);
-  background-color: #fff;
-  border-color: #d9d9d9;
-}
-
-.example-btn:hover {
-  color: #4AB7BD;
-  background-color: #fff;
-  border-color: #4AB7BD;
-}
-.example {
-  font-size: 50px;
-  color: #F6416C;
-  display: block;
-  margin: 10px 0;
-  text-align: center;
-  font-size: 80px;
-  font-weight: 500;
-}
-
-.label {
-  color: #2f4f4f;
-  font-size: 16px;
-  display: inline-block;
-  margin: 15px 30px 15px 0;
-}
-
-input {
-  position: relative;
-  display: inline-block;
-  padding: 4px 7px;
-  width: 70px;
-  height: 28px;
-  cursor: text;
-  font-size: 12px;
-  line-height: 1.5;
-  color: rgba(0, 0, 0, .65);
-  background-color: #fff;
-  background-image: none;
-  border: 1px solid #d9d9d9;
-  border-radius: 4px;
-  -webkit-transition: all .3s;
-  transition: all .3s;
-}
-
-.startBtn {
-  margin-left: 20px;
-  font-size: 20px;
-  color: #30B08F;
-  background-color: #fff;
-}
-
-.startBtn:hover {
-  background-color: #30B08F;
-  color: #fff;
-  border-color: #30B08F;
-}
-
-.pause-resume-btn {
-  font-size: 20px;
-  color: #E65D6E;
-  background-color: #fff;
-}
-
-.pause-resume-btn:hover {
-  background-color: #E65D6E;
-  color: #fff;
-  border-color: #E65D6E;
-}
-</style>
-

+ 0 - 39
src/views/components-demo/dnd-list.vue

@@ -1,39 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>drag-list base on
-      <a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a>
-    </aside>
-    <div class="editor-container">
-      <dnd-list :list1="list1" :list2="list2" list1-title="List" list2-title="Article pool" />
-    </div>
-  </div>
-</template>
-
-<script>
-import DndList from '@/components/DndList'
-import { fetchList } from '@/api/article'
-
-export default {
-  name: 'DndListDemo',
-  components: { DndList },
-  data() {
-    return {
-      list1: [],
-      list2: []
-    }
-  },
-  created() {
-    this.getData()
-  },
-  methods: {
-    getData() {
-      this.listLoading = true
-      fetchList().then(response => {
-        this.list1 = response.data.items.splice(0, 5)
-        this.list2 = response.data.items
-      })
-    }
-  }
-}
-</script>
-

+ 0 - 61
src/views/components-demo/drag-dialog.vue

@@ -1,61 +0,0 @@
-<template>
-  <div class="components-container">
-    <el-button type="primary" @click="dialogTableVisible = true">
-      open a Drag Dialog
-    </el-button>
-    <el-dialog v-el-drag-dialog :visible.sync="dialogTableVisible" title="Shipping address" @dragDialog="handleDrag">
-      <el-select ref="select" v-model="value" placeholder="请选择">
-        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
-      </el-select>
-      <el-table :data="gridData">
-        <el-table-column property="date" label="Date" width="150" />
-        <el-table-column property="name" label="Name" width="200" />
-        <el-table-column property="address" label="Address" />
-      </el-table>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
-
-export default {
-  name: 'DragDialogDemo',
-  directives: { elDragDialog },
-  data() {
-    return {
-      dialogTableVisible: false,
-      options: [
-        { value: '选项1', label: '黄金糕' },
-        { value: '选项2', label: '双皮奶' },
-        { value: '选项3', label: '蚵仔煎' },
-        { value: '选项4', label: '龙须面' }
-      ],
-      value: '',
-      gridData: [{
-        date: '2016-05-02',
-        name: 'John Smith',
-        address: 'No.1518,  Jinshajiang Road, Putuo District'
-      }, {
-        date: '2016-05-04',
-        name: 'John Smith',
-        address: 'No.1518,  Jinshajiang Road, Putuo District'
-      }, {
-        date: '2016-05-01',
-        name: 'John Smith',
-        address: 'No.1518,  Jinshajiang Road, Putuo District'
-      }, {
-        date: '2016-05-03',
-        name: 'John Smith',
-        address: 'No.1518,  Jinshajiang Road, Putuo District'
-      }]
-    }
-  },
-  methods: {
-    // v-el-drag-dialog onDrag callback function
-    handleDrag() {
-      this.$refs.select.blur()
-    }
-  }
-}
-</script>

+ 0 - 66
src/views/components-demo/drag-kanban.vue

@@ -1,66 +0,0 @@
-<template>
-  <div class="components-container board">
-    <Kanban :key="1" :list="list1" :group="group" class="kanban todo" header-text="Todo" />
-    <Kanban :key="2" :list="list2" :group="group" class="kanban working" header-text="Working" />
-    <Kanban :key="3" :list="list3" :group="group" class="kanban done" header-text="Done" />
-  </div>
-</template>
-<script>
-import Kanban from '@/components/Kanban'
-
-export default {
-  name: 'DragKanbanDemo',
-  components: {
-    Kanban
-  },
-  data() {
-    return {
-      group: 'mission',
-      list1: [
-        { name: 'Mission', id: 1 },
-        { name: 'Mission', id: 2 },
-        { name: 'Mission', id: 3 },
-        { name: 'Mission', id: 4 }
-      ],
-      list2: [
-        { name: 'Mission', id: 5 },
-        { name: 'Mission', id: 6 },
-        { name: 'Mission', id: 7 }
-      ],
-      list3: [
-        { name: 'Mission', id: 8 },
-        { name: 'Mission', id: 9 },
-        { name: 'Mission', id: 10 }
-      ]
-    }
-  }
-}
-</script>
-<style lang="scss">
-.board {
-  width: 1000px;
-  margin-left: 20px;
-  display: flex;
-  justify-content: space-around;
-  flex-direction: row;
-  align-items: flex-start;
-}
-.kanban {
-  &.todo {
-    .board-column-header {
-      background: #4A9FF9;
-    }
-  }
-  &.working {
-    .board-column-header {
-      background: #f9944a;
-    }
-  }
-  &.done {
-    .board-column-header {
-      background: #2ac06d;
-    }
-  }
-}
-</style>
-

+ 0 - 43
src/views/components-demo/drag-select.vue

@@ -1,43 +0,0 @@
-<template>
-  <div class="components-container">
-    <el-drag-select v-model="value" style="width:500px;" multiple placeholder="请选择">
-      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
-    </el-drag-select>
-
-    <div style="margin-top:30px;">
-      <el-tag v-for="item of value" :key="item" style="margin-right:15px;">
-        {{ item }}
-      </el-tag>
-    </div>
-  </div>
-</template>
-
-<script>
-import ElDragSelect from '@/components/DragSelect' // base on element-ui
-
-export default {
-  name: 'DragSelectDemo',
-  components: { ElDragSelect },
-  data() {
-    return {
-      value: ['Apple', 'Banana', 'Orange'],
-      options: [{
-        value: 'Apple',
-        label: 'Apple'
-      }, {
-        value: 'Banana',
-        label: 'Banana'
-      }, {
-        value: 'Orange',
-        label: 'Orange'
-      }, {
-        value: 'Pear',
-        label: 'Pear'
-      }, {
-        value: 'Strawberry',
-        label: 'Strawberry'
-      }]
-    }
-  }
-}
-</script>

+ 0 - 31
src/views/components-demo/dropzone.vue

@@ -1,31 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>
-      Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
-      Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.
-    </aside>
-    <div class="editor-container">
-      <dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" />
-    </div>
-  </div>
-</template>
-
-<script>
-import Dropzone from '@/components/Dropzone'
-
-export default {
-  name: 'DropzoneDemo',
-  components: { Dropzone },
-  methods: {
-    dropzoneS(file) {
-      console.log(file)
-      this.$message({ message: 'Upload success', type: 'success' })
-    },
-    dropzoneR(file) {
-      console.log(file)
-      this.$message({ message: 'Delete success', type: 'success' })
-    }
-  }
-}
-</script>
-

ファイルの差分が大きいため隠しています
+ 0 - 36
src/views/components-demo/json-editor.vue


+ 0 - 101
src/views/components-demo/markdown.vue

@@ -1,101 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>Markdown is based on
-      <a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,simply wrapped with Vue.
-      <a
-        target="_blank"
-        href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html"
-      >
-        Documentation </a>
-    </aside>
-
-    <div class="editor-container">
-      <el-tag class="tag-title">
-        Basic:
-      </el-tag>
-      <markdown-editor v-model="content1" height="300px" />
-    </div>
-
-    <div class="editor-container">
-      <el-tag class="tag-title">
-        Markdown Mode:
-      </el-tag>
-      <markdown-editor ref="markdownEditor" v-model="content2" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px" />
-    </div>
-
-    <div class="editor-container">
-      <el-tag class="tag-title">
-        Customize Toolbar:
-      </el-tag>
-      <markdown-editor v-model="content3" :options="{ toolbarItems: ['heading','bold','italic']}" />
-    </div>
-
-    <div class="editor-container">
-      <el-tag class="tag-title">
-        I18n:
-      </el-tag>
-      <el-alert
-        :closable="false"
-        title="You can change the language of the admin system to see the effect"
-        type="success"
-      />
-      <markdown-editor ref="markdownEditor" v-model="content4" :language="language" height="300px" />
-    </div>
-
-    <el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">
-      Get HTML
-    </el-button>
-    <div v-html="html" />
-  </div>
-</template>
-
-<script>
-import MarkdownEditor from '@/components/MarkdownEditor'
-
-const content = `
-**This is test**
-
-* vue
-* element
-* webpack
-
-`
-export default {
-  name: 'MarkdownDemo',
-  components: { MarkdownEditor },
-  data() {
-    return {
-      content1: content,
-      content2: content,
-      content3: content,
-      content4: content,
-      html: '',
-      languageTypeList: {
-        'en': 'en_US',
-        'zh': 'zh_CN',
-        'es': 'es_ES'
-      }
-    }
-  },
-  computed: {
-    language() {
-      return this.languageTypeList['en']
-    }
-  },
-  methods: {
-    getHtml() {
-      this.html = this.$refs.markdownEditor.getHtml()
-      console.log(this.html)
-    }
-  }
-}
-</script>
-
-<style scoped>
-.editor-container{
-  margin-bottom: 30px;
-}
-.tag-title{
-  margin-bottom: 5px;
-}
-</style>

+ 0 - 169
src/views/components-demo/mixin.vue

@@ -1,169 +0,0 @@
-<template>
-  <div class="mixin-components-container">
-    <el-row>
-      <el-card class="box-card">
-        <div slot="header" class="clearfix">
-          <span>Buttons</span>
-        </div>
-        <div style="margin-bottom:50px;">
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn blue-btn" to="/documentation/index">
-              Documentation
-            </router-link>
-          </el-col>
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn light-blue-btn" to="/icon/index">
-              Icons
-            </router-link>
-          </el-col>
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn pink-btn" to="/excel/export-excel">
-              Excel
-            </router-link>
-          </el-col>
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn green-btn" to="/table/complex-table">
-              Table
-            </router-link>
-          </el-col>
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn tiffany-btn" to="/example/create">
-              Form
-            </router-link>
-          </el-col>
-          <el-col :span="4" class="text-center">
-            <router-link class="pan-btn yellow-btn" to="/theme/index">
-              Theme
-            </router-link>
-          </el-col>
-        </div>
-      </el-card>
-    </el-row>
-
-    <el-row :gutter="20" style="margin-top:50px;">
-      <el-col :span="6">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>Material Design 的input</span>
-          </div>
-          <div style="height:100px;">
-            <el-form :model="demo" :rules="demoRules">
-              <el-form-item prop="title">
-                <md-input v-model="demo.title" icon="el-icon-search" name="title" placeholder="输入标题">
-                  标题
-                </md-input>
-              </el-form-item>
-            </el-form>
-          </div>
-        </el-card>
-      </el-col>
-
-      <el-col :span="6">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>图片hover效果</span>
-          </div>
-          <div class="component-item">
-            <pan-thumb width="100px" height="100px" image="https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191">
-              vue-element-admin
-            </pan-thumb>
-          </div>
-        </el-card>
-      </el-col>
-
-      <el-col :span="6">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>水波纹 waves v-directive</span>
-          </div>
-          <div class="component-item">
-            <el-button v-waves type="primary">
-              水波纹效果
-            </el-button>
-          </div>
-        </el-card>
-      </el-col>
-
-      <el-col :span="6">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>hover text</span>
-          </div>
-          <div class="component-item">
-            <mallki class-name="mallki-text" text="vue-element-admin" />
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20" style="margin-top:50px;">
-      <el-col :span="8">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>Share</span>
-          </div>
-          <div class="component-item" style="height:420px;">
-            <dropdown-menu :items="articleList" style="margin:0 auto;" title="系列文章" />
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import PanThumb from '@/components/PanThumb'
-import MdInput from '@/components/MDinput'
-import Mallki from '@/components/TextHoverEffect/Mallki'
-import DropdownMenu from '@/components/Share/DropdownMenu'
-import waves from '@/directive/waves/index.js' // 水波纹指令
-
-export default {
-  name: 'ComponentMixinDemo',
-  components: {
-    PanThumb,
-    MdInput,
-    Mallki,
-    DropdownMenu
-  },
-  directives: {
-    waves
-  },
-  data() {
-    const validate = (rule, value, callback) => {
-      if (value.length !== 6) {
-        callback(new Error('请输入六个字符'))
-      } else {
-        callback()
-      }
-    }
-    return {
-      demo: {
-        title: ''
-      },
-      demoRules: {
-        title: [{ required: true, trigger: 'change', validator: validate }]
-      },
-      articleList: [
-        { title: '基础篇', href: 'https://juejin.im/post/59097cd7a22b9d0065fb61d2' },
-        { title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' },
-        { title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' },
-        { title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' },
-        { title: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' },
-        { title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }
-      ]
-    }
-  }
-}
-</script>
-
-<style scoped>
-.mixin-components-container {
-  background-color: #f0f2f5;
-  padding: 30px;
-  min-height: calc(100vh - 84px);
-}
-.component-item{
-  min-height: 100px;
-}
-</style>

+ 0 - 67
src/views/components-demo/split-pane.vue

@@ -1,67 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside><strong>SplitPane</strong> If you've used
-      <a href="https://codepen.io/" target="_blank"> codepen</a>,
-      <a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar.
-      <a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a>
-    </aside>
-    <split-pane split="vertical" @resize="resize">
-      <template slot="paneL">
-        <div class="left-container" />
-      </template>
-      <template slot="paneR">
-        <split-pane split="horizontal">
-          <template slot="paneL">
-            <div class="top-container" />
-          </template>
-          <template slot="paneR">
-            <div class="bottom-container" />
-          </template>
-        </split-pane>
-      </template>
-    </split-pane>
-  </div>
-</template>
-
-<script>
-import splitPane from 'vue-splitpane'
-
-export default {
-  name: 'SplitpaneDemo',
-  components: { splitPane },
-  methods: {
-    resize() {
-      console.log('resize')
-    }
-  }
-}
-</script>
-
-<style  scoped>
-  .components-container {
-    position: relative;
-    height: 100vh;
-  }
-
-  .left-container {
-    background-color: #F38181;
-    height: 100%;
-  }
-
-  .right-container {
-    background-color: #FCE38A;
-    height: 200px;
-  }
-
-  .top-container {
-    background-color: #FCE38A;
-    width: 100%;
-    height: 100%;
-  }
-
-  .bottom-container {
-    width: 100%;
-    background-color: #95E1D3;
-    height: 100%;
-  }
-</style>

+ 0 - 135
src/views/components-demo/sticky.vue

@@ -1,135 +0,0 @@
-<template>
-  <div>
-    <sticky :z-index="10" class-name="sub-navbar">
-      <el-dropdown trigger="click">
-        <el-button plain>
-          Platform<i class="el-icon-caret-bottom el-icon--right" />
-        </el-button>
-        <el-dropdown-menu slot="dropdown" class="no-border">
-          <el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
-            <el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key">
-              {{ item.name }}
-            </el-checkbox>
-          </el-checkbox-group>
-        </el-dropdown-menu>
-      </el-dropdown>
-
-      <el-dropdown trigger="click">
-        <el-button plain>
-          Link<i class="el-icon-caret-bottom el-icon--right" />
-        </el-button>
-        <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:300px">
-          <el-input v-model="url" placeholder="Please enter the content">
-            <template slot="prepend">
-              Url
-            </template>
-          </el-input>
-        </el-dropdown-menu>
-      </el-dropdown>
-
-      <div class="time-container">
-        <el-date-picker v-model="time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" />
-      </div>
-
-      <el-button style="margin-left: 10px;" type="success">
-        publish
-      </el-button>
-    </sticky>
-
-    <div class="components-container">
-      <aside>
-        Sticky header, When the page is scrolled to the preset position will be sticky on the top.
-      </aside>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <sticky :sticky-top="200">
-        <el-button type="primary"> placeholder</el-button>
-      </sticky>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-      <div>placeholder</div>
-    </div>
-  </div>
-</template>
-
-<script>
-import Sticky from '@/components/Sticky'
-
-export default {
-  name: 'StickyDemo',
-  components: { Sticky },
-  data() {
-    return {
-      time: '',
-      url: '',
-      platforms: ['a-platform'],
-      platformsOptions: [
-        { key: 'a-platform', name: 'platformA' },
-        { key: 'b-platform', name: 'platformB' },
-        { key: 'c-platform', name: 'platformC' }
-      ],
-      pickerOptions: {
-        disabledDate(time) {
-          return time.getTime() > Date.now()
-        }
-      }
-    }
-  }
-}
-</script>
-
-<style scoped>
-.components-container div {
-  margin: 10px;
-}
-
-.time-container {
-  display: inline-block;
-}
-</style>

+ 0 - 36
src/views/components-demo/tinymce.vue

@@ -1,36 +0,0 @@
-<template>
-  <div class="components-container">
-    <aside>
-      Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.
-      <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html">Documentation</a>
-    </aside>
-    <div>
-      <tinymce v-model="content" :height="300" />
-    </div>
-    <div class="editor-content" v-html="content" />
-  </div>
-</template>
-
-<script>
-import Tinymce from '@/components/Tinymce'
-
-export default {
-  name: 'TinymceDemo',
-  components: { Tinymce },
-  data() {
-    return {
-      content:
-      `<h1 style="text-align: center;">Welcome to the TinyMCE demo!</h1><p style="text-align: center; font-size: 15px;"><img title="TinyMCE Logo" src="//www.tinymce.com/images/glyph-tinymce@2x.png" alt="TinyMCE Logo" width="110" height="97" /><ul>
-        <li>Our <a href="//www.tinymce.com/docs/">documentation</a> is a great resource for learning how to configure TinyMCE.</li><li>Have a specific question? Visit the <a href="https://community.tinymce.com/forum/">Community Forum</a>.</li><li>We also offer enterprise grade support as part of <a href="https://tinymce.com/pricing">TinyMCE premium subscriptions</a>.</li>
-      </ul>`
-    }
-  }
-}
-</script>
-
-<style scoped>
-.editor-content{
-  margin-top: 20px;
-}
-</style>
-

+ 0 - 13
src/views/error-log/components/ErrorTestA.vue

@@ -1,13 +0,0 @@
-<template>
-  <div>
-    <!--error code-->
-    {{ a.a }}
-    <!--error code-->
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'ErrorTestA'
-}
-</script>

+ 0 - 11
src/views/error-log/components/ErrorTestB.vue

@@ -1,11 +0,0 @@
-<template>
-  <div />
-</template>
-
-<script>
-export default {
-  created() {
-    this.b = b // eslint-disable-line
-  }
-}
-</script>

+ 0 - 32
src/views/error-log/index.vue

@@ -1,32 +0,0 @@
-<template>
-  <div class="errPage-container">
-    <ErrorA />
-    <ErrorB />
-    <h3>Please click the bug icon in the upper right corner</h3>
-    <aside>
-      Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.
-      <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html">
-        Document introduction
-      </a>
-    </aside>
-    <a href="#">
-      <img src="https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif">
-    </a>
-  </div>
-</template>
-
-<script>
-import ErrorA from './components/ErrorTestA'
-import ErrorB from './components/ErrorTestB'
-
-export default {
-  name: 'ErrorLog',
-  components: { ErrorA, ErrorB }
-}
-</script>
-
-<style scoped>
-  .errPage-container {
-    padding: 30px;
-  }
-</style>

+ 0 - 289
src/views/example/components/ArticleDetail.vue

@@ -1,289 +0,0 @@
-<template>
-  <div class="createPost-container">
-    <el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
-
-      <sticky :z-index="10" :class-name="'sub-navbar '+postForm.status">
-        <CommentDropdown v-model="postForm.comment_disabled" />
-        <PlatformDropdown v-model="postForm.platforms" />
-        <SourceUrlDropdown v-model="postForm.source_uri" />
-        <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">
-          Publish
-        </el-button>
-        <el-button v-loading="loading" type="warning" @click="draftForm">
-          Draft
-        </el-button>
-      </sticky>
-
-      <div class="createPost-main-container">
-        <el-row>
-          <Warning />
-
-          <el-col :span="24">
-            <el-form-item style="margin-bottom: 40px;" prop="title">
-              <MDinput v-model="postForm.title" :maxlength="100" name="name" required>
-                Title
-              </MDinput>
-            </el-form-item>
-
-            <div class="postInfo-container">
-              <el-row>
-                <el-col :span="8">
-                  <el-form-item label-width="60px" label="Author:" class="postInfo-container-item">
-                    <el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="Search user">
-                      <el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item" />
-                    </el-select>
-                  </el-form-item>
-                </el-col>
-
-                <el-col :span="10">
-                  <el-form-item label-width="120px" label="Publish Time:" class="postInfo-container-item">
-                    <el-date-picker v-model="displayTime" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Select date and time" />
-                  </el-form-item>
-                </el-col>
-
-                <el-col :span="6">
-                  <el-form-item label-width="90px" label="Importance:" class="postInfo-container-item">
-                    <el-rate
-                      v-model="postForm.importance"
-                      :max="3"
-                      :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
-                      :low-threshold="1"
-                      :high-threshold="3"
-                      style="display:inline-block"
-                    />
-                  </el-form-item>
-                </el-col>
-              </el-row>
-            </div>
-          </el-col>
-        </el-row>
-
-        <el-form-item style="margin-bottom: 40px;" label-width="70px" label="Summary:">
-          <el-input v-model="postForm.content_short" :rows="1" type="textarea" class="article-textarea" autosize placeholder="Please enter the content" />
-          <span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}words</span>
-        </el-form-item>
-
-        <el-form-item prop="content" style="margin-bottom: 30px;">
-          <Tinymce ref="editor" v-model="postForm.content" :height="400" />
-        </el-form-item>
-
-        <el-form-item prop="image_uri" style="margin-bottom: 30px;">
-          <Upload v-model="postForm.image_uri" />
-        </el-form-item>
-      </div>
-    </el-form>
-  </div>
-</template>
-
-<script>
-import Tinymce from '@/components/Tinymce'
-import Upload from '@/components/Upload/SingleImage3'
-import MDinput from '@/components/MDinput'
-import Sticky from '@/components/Sticky' // 粘性header组件
-import { validURL } from '@/utils/validate'
-import { fetchArticle } from '@/api/article'
-import { searchUser } from '@/api/remote-search'
-import Warning from './Warning'
-import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
-
-const defaultForm = {
-  status: 'draft',
-  title: '', // 文章题目
-  content: '', // 文章内容
-  content_short: '', // 文章摘要
-  source_uri: '', // 文章外链
-  image_uri: '', // 文章图片
-  display_time: undefined, // 前台展示时间
-  id: undefined,
-  platforms: ['a-platform'],
-  comment_disabled: false,
-  importance: 0
-}
-
-export default {
-  name: 'ArticleDetail',
-  components: { Tinymce, MDinput, Upload, Sticky, Warning, CommentDropdown, PlatformDropdown, SourceUrlDropdown },
-  props: {
-    isEdit: {
-      type: Boolean,
-      default: false
-    }
-  },
-  data() {
-    const validateRequire = (rule, value, callback) => {
-      if (value === '') {
-        this.$message({
-          message: rule.field + '为必传项',
-          type: 'error'
-        })
-        callback(new Error(rule.field + '为必传项'))
-      } else {
-        callback()
-      }
-    }
-    const validateSourceUri = (rule, value, callback) => {
-      if (value) {
-        if (validURL(value)) {
-          callback()
-        } else {
-          this.$message({
-            message: '外链url填写不正确',
-            type: 'error'
-          })
-          callback(new Error('外链url填写不正确'))
-        }
-      } else {
-        callback()
-      }
-    }
-    return {
-      postForm: Object.assign({}, defaultForm),
-      loading: false,
-      userListOptions: [],
-      rules: {
-        image_uri: [{ validator: validateRequire }],
-        title: [{ validator: validateRequire }],
-        content: [{ validator: validateRequire }],
-        source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
-      },
-      tempRoute: {}
-    }
-  },
-  computed: {
-    contentShortLength() {
-      return this.postForm.content_short.length
-    },
-    displayTime: {
-      // set and get is useful when the data
-      // returned by the back end api is different from the front end
-      // back end return => "2013-06-25 06:59:25"
-      // front end need timestamp => 1372114765000
-      get() {
-        return (+new Date(this.postForm.display_time))
-      },
-      set(val) {
-        this.postForm.display_time = new Date(val)
-      }
-    }
-  },
-  created() {
-    if (this.isEdit) {
-      const id = this.$route.params && this.$route.params.id
-      this.fetchData(id)
-    }
-
-    // Why need to make a copy of this.$route here?
-    // Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
-    // https://github.com/PanJiaChen/vue-element-admin/issues/1221
-    this.tempRoute = Object.assign({}, this.$route)
-  },
-  methods: {
-    fetchData(id) {
-      fetchArticle(id).then(response => {
-        this.postForm = response.data
-
-        // just for test
-        this.postForm.title += `   Article Id:${this.postForm.id}`
-        this.postForm.content_short += `   Article Id:${this.postForm.id}`
-
-        // set tagsview title
-        this.setTagsViewTitle()
-
-        // set page title
-        this.setPageTitle()
-      }).catch(err => {
-        console.log(err)
-      })
-    },
-    setTagsViewTitle() {
-      const title = 'Edit Article'
-      const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
-      this.$store.dispatch('tagsView/updateVisitedView', route)
-    },
-    setPageTitle() {
-      const title = 'Edit Article'
-      document.title = `${title} - ${this.postForm.id}`
-    },
-    submitForm() {
-      console.log(this.postForm)
-      this.$refs.postForm.validate(valid => {
-        if (valid) {
-          this.loading = true
-          this.$notify({
-            title: '成功',
-            message: '发布文章成功',
-            type: 'success',
-            duration: 2000
-          })
-          this.postForm.status = 'published'
-          this.loading = false
-        } else {
-          console.log('error submit!!')
-          return false
-        }
-      })
-    },
-    draftForm() {
-      if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
-        this.$message({
-          message: '请填写必要的标题和内容',
-          type: 'warning'
-        })
-        return
-      }
-      this.$message({
-        message: '保存成功',
-        type: 'success',
-        showClose: true,
-        duration: 1000
-      })
-      this.postForm.status = 'draft'
-    },
-    getRemoteUserList(query) {
-      searchUser(query).then(response => {
-        if (!response.data.items) return
-        this.userListOptions = response.data.items.map(v => v.name)
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-@import "~@/styles/mixin.scss";
-
-.createPost-container {
-  position: relative;
-
-  .createPost-main-container {
-    padding: 40px 45px 20px 50px;
-
-    .postInfo-container {
-      position: relative;
-      @include clearfix;
-      margin-bottom: 10px;
-
-      .postInfo-container-item {
-        float: left;
-      }
-    }
-  }
-
-  .word-counter {
-    width: 40px;
-    position: absolute;
-    right: 10px;
-    top: 0px;
-  }
-}
-
-.article-textarea ::v-deep {
-  textarea {
-    padding-right: 40px;
-    resize: none;
-    border: none;
-    border-radius: 0px;
-    border-bottom: 1px solid #bfcbd9;
-  }
-}
-</style>

+ 0 - 41
src/views/example/components/Dropdown/Comment.vue

@@ -1,41 +0,0 @@
-<template>
-  <el-dropdown :show-timeout="100" trigger="click">
-    <el-button plain>
-      {{ !comment_disabled?'Comment: opened':'Comment: closed' }}
-      <i class="el-icon-caret-bottom el-icon--right" />
-    </el-button>
-    <el-dropdown-menu slot="dropdown" class="no-padding">
-      <el-dropdown-item>
-        <el-radio-group v-model="comment_disabled" style="padding: 10px;">
-          <el-radio :label="true">
-            Close comment
-          </el-radio>
-          <el-radio :label="false">
-            Open comment
-          </el-radio>
-        </el-radio-group>
-      </el-dropdown-item>
-    </el-dropdown-menu>
-  </el-dropdown>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      type: Boolean,
-      default: false
-    }
-  },
-  computed: {
-    comment_disabled: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 46
src/views/example/components/Dropdown/Platform.vue

@@ -1,46 +0,0 @@
-<template>
-  <el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
-    <el-button plain>
-      Platfroms({{ platforms.length }})
-      <i class="el-icon-caret-bottom el-icon--right" />
-    </el-button>
-    <el-dropdown-menu slot="dropdown" class="no-border">
-      <el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
-        <el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key">
-          {{ item.name }}
-        </el-checkbox>
-      </el-checkbox-group>
-    </el-dropdown-menu>
-  </el-dropdown>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      required: true,
-      default: () => [],
-      type: Array
-    }
-  },
-  data() {
-    return {
-      platformsOptions: [
-        { key: 'a-platform', name: 'a-platform' },
-        { key: 'b-platform', name: 'b-platform' },
-        { key: 'c-platform', name: 'c-platform' }
-      ]
-    }
-  },
-  computed: {
-    platforms: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 38
src/views/example/components/Dropdown/SourceUrl.vue

@@ -1,38 +0,0 @@
-<template>
-  <el-dropdown :show-timeout="100" trigger="click">
-    <el-button plain>
-      Link
-      <i class="el-icon-caret-bottom el-icon--right" />
-    </el-button>
-    <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">
-      <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
-        <el-input v-model="source_uri" placeholder="Please enter the content">
-          <template slot="prepend">
-            URL
-          </template>
-        </el-input>
-      </el-form-item>
-    </el-dropdown-menu>
-  </el-dropdown>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      type: String,
-      default: ''
-    }
-  },
-  computed: {
-    source_uri: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 3
src/views/example/components/Dropdown/index.js

@@ -1,3 +0,0 @@
-export { default as CommentDropdown } from './Comment'
-export { default as PlatformDropdown } from './Platform'
-export { default as SourceUrlDropdown } from './SourceUrl'

+ 0 - 13
src/views/example/components/Warning.vue

@@ -1,13 +0,0 @@
-<template>
-  <aside>
-    Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support
-    caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching
-    effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all
-    pages directly. See details
-    <a
-      href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
-      target="_blank"
-    >Document</a>
-  </aside>
-</template>
-

+ 0 - 13
src/views/example/create.vue

@@ -1,13 +0,0 @@
-<template>
-  <article-detail :is-edit="false" />
-</template>
-
-<script>
-import ArticleDetail from './components/ArticleDetail'
-
-export default {
-  name: 'CreateArticle',
-  components: { ArticleDetail }
-}
-</script>
-

+ 0 - 13
src/views/example/edit.vue

@@ -1,13 +0,0 @@
-<template>
-  <article-detail :is-edit="true" />
-</template>
-
-<script>
-import ArticleDetail from './components/ArticleDetail'
-
-export default {
-  name: 'EditForm',
-  components: { ArticleDetail }
-}
-</script>
-

+ 0 - 112
src/views/example/list.vue

@@ -1,112 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
-      <el-table-column align="center" label="ID" width="80">
-        <template slot-scope="scope">
-          <span>{{ scope.row.id }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="180px" align="center" label="Date">
-        <template slot-scope="scope">
-          <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="120px" align="center" label="Author">
-        <template slot-scope="scope">
-          <span>{{ scope.row.author }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="100px" label="Importance">
-        <template slot-scope="scope">
-          <svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" />
-        </template>
-      </el-table-column>
-
-      <el-table-column class-name="status-col" label="Status" width="110">
-        <template slot-scope="{row}">
-          <el-tag :type="row.status | statusFilter">
-            {{ row.status }}
-          </el-tag>
-        </template>
-      </el-table-column>
-
-      <el-table-column min-width="300px" label="Title">
-        <template slot-scope="{row}">
-          <router-link :to="'/example/edit/'+row.id" class="link-type">
-            <span>{{ row.title }}</span>
-          </router-link>
-        </template>
-      </el-table-column>
-
-      <el-table-column align="center" label="Actions" width="120">
-        <template slot-scope="scope">
-          <router-link :to="'/example/edit/'+scope.row.id">
-            <el-button type="primary" size="small" icon="el-icon-edit">
-              Edit
-            </el-button>
-          </router-link>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
-
-export default {
-  name: 'ArticleList',
-  components: { Pagination },
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'info',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  data() {
-    return {
-      list: null,
-      total: 0,
-      listLoading: true,
-      listQuery: {
-        page: 1,
-        limit: 20
-      }
-    }
-  },
-  created() {
-    this.getList()
-  },
-  methods: {
-    getList() {
-      this.listLoading = true
-      fetchList(this.listQuery).then(response => {
-        this.list = response.data.items
-        this.total = response.data.total
-        this.listLoading = false
-      })
-    }
-  }
-}
-</script>
-
-<style scoped>
-.edit-input {
-  padding-right: 100px;
-}
-.cancel-btn {
-  position: absolute;
-  right: 15px;
-  top: 10px;
-}
-</style>

+ 0 - 34
src/views/excel/components/AutoWidthOption.vue

@@ -1,34 +0,0 @@
-<template>
-  <div style="display:inline-block;">
-    <label class="radio-label">Cell Auto-Width: </label>
-    <el-radio-group v-model="autoWidth">
-      <el-radio :label="true" border>
-        True
-      </el-radio>
-      <el-radio :label="false" border>
-        False
-      </el-radio>
-    </el-radio-group>
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      type: Boolean,
-      default: true
-    }
-  },
-  computed: {
-    autoWidth: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 39
src/views/excel/components/BookTypeOption.vue

@@ -1,39 +0,0 @@
-<template>
-  <div style="display:inline-block;">
-    <label class="radio-label">Book Type: </label>
-    <el-select v-model="bookType" style="width:120px;">
-      <el-option
-        v-for="item in options"
-        :key="item"
-        :label="item"
-        :value="item"
-      />
-    </el-select>
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      type: String,
-      default: 'xlsx'
-    }
-  },
-  data() {
-    return {
-      options: ['xlsx', 'csv', 'txt']
-    }
-  },
-  computed: {
-    bookType: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 27
src/views/excel/components/FilenameOption.vue

@@ -1,27 +0,0 @@
-<template>
-  <div style="display:inline-block;">
-    <label class="radio-label" style="padding-left:0;">Filename: </label>
-    <el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:345px;" prefix-icon="el-icon-document" />
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    value: {
-      type: String,
-      default: ''
-    }
-  },
-  computed: {
-    filename: {
-      get() {
-        return this.value
-      },
-      set(val) {
-        this.$emit('input', val)
-      }
-    }
-  }
-}
-</script>

+ 0 - 116
src/views/excel/export-excel.vue

@@ -1,116 +0,0 @@
-<template>
-  <div class="app-container">
-
-    <div>
-      <FilenameOption v-model="filename" />
-      <AutoWidthOption v-model="autoWidth" />
-      <BookTypeOption v-model="bookType" />
-      <el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="el-icon-document" @click="handleDownload">
-        Export Excel
-      </el-button>
-      <a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
-        <el-tag type="info">Documentation</el-tag>
-      </a>
-    </div>
-
-    <el-table v-loading="listLoading" :data="list" element-loading-text="Loading..." border fit highlight-current-row>
-      <el-table-column align="center" label="Id" width="95">
-        <template slot-scope="scope">
-          {{ scope.$index }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Title">
-        <template slot-scope="scope">
-          {{ scope.row.title }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Author" width="110" align="center">
-        <template slot-scope="scope">
-          <el-tag>{{ scope.row.author }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="Readings" width="115" align="center">
-        <template slot-scope="scope">
-          {{ scope.row.pageviews }}
-        </template>
-      </el-table-column>
-      <el-table-column align="center" label="Date" width="220">
-        <template slot-scope="scope">
-          <i class="el-icon-time" />
-          <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-import { parseTime } from '@/utils'
-// options components
-import FilenameOption from './components/FilenameOption'
-import AutoWidthOption from './components/AutoWidthOption'
-import BookTypeOption from './components/BookTypeOption'
-
-export default {
-  name: 'ExportExcel',
-  components: { FilenameOption, AutoWidthOption, BookTypeOption },
-  data() {
-    return {
-      list: null,
-      listLoading: true,
-      downloadLoading: false,
-      filename: '',
-      autoWidth: true,
-      bookType: 'xlsx'
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      this.listLoading = true
-      fetchList().then(response => {
-        this.list = response.data.items
-        this.listLoading = false
-      })
-    },
-    handleDownload() {
-      this.downloadLoading = true
-      import('@/vendor/Export2Excel').then(excel => {
-        const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
-        const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
-        const list = this.list
-        const data = this.formatJson(filterVal, list)
-        excel.export_json_to_excel({
-          header: tHeader,
-          data,
-          filename: this.filename,
-          autoWidth: this.autoWidth,
-          bookType: this.bookType
-        })
-        this.downloadLoading = false
-      })
-    },
-    formatJson(filterVal, jsonData) {
-      return jsonData.map(v => filterVal.map(j => {
-        if (j === 'timestamp') {
-          return parseTime(v[j])
-        } else {
-          return v[j]
-        }
-      }))
-    }
-  }
-}
-</script>
-
-<style>
-.radio-label {
-  font-size: 14px;
-  color: #606266;
-  line-height: 40px;
-  padding: 0 12px 0 30px;
-}
-</style>

+ 0 - 101
src/views/excel/merge-header.vue

@@ -1,101 +0,0 @@
-<template>
-  <div class="app-container">
-
-    <el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">Export</el-button>
-
-    <el-table
-      ref="multipleTable"
-      v-loading="listLoading"
-      :data="list"
-      element-loading-text="Loading"
-      border
-      fit
-      highlight-current-row
-    >
-      <el-table-column align="center" label="Id" width="95">
-        <template slot-scope="scope">
-          {{ scope.$index }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Main Information" align="center">
-        <el-table-column label="Title">
-          <template slot-scope="scope">
-            {{ scope.row.title }}
-          </template>
-        </el-table-column>
-        <el-table-column label="Author" width="110" align="center">
-          <template slot-scope="scope">
-            <el-tag>{{ scope.row.author }}</el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column label="Readings" width="115" align="center">
-          <template slot-scope="scope">
-            {{ scope.row.pageviews }}
-          </template>
-        </el-table-column>
-      </el-table-column>
-      <el-table-column align="center" label="Date" width="220">
-        <template slot-scope="scope">
-          <i class="el-icon-time" />
-          <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
-
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-import { parseTime } from '@/utils'
-
-export default {
-  name: 'MergeHeader',
-  data() {
-    return {
-      list: null,
-      listLoading: true,
-      downloadLoading: false
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      this.listLoading = true
-      fetchList(this.listQuery).then(response => {
-        this.list = response.data.items
-        this.listLoading = false
-      })
-    },
-    handleDownload() {
-      this.downloadLoading = true
-      import('@/vendor/Export2Excel').then(excel => {
-        const multiHeader = [['Id', 'Main Information', '', '', 'Date']]
-        const header = ['', 'Title', 'Author', 'Readings', '']
-        const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
-        const list = this.list
-        const data = this.formatJson(filterVal, list)
-        const merges = ['A1:A2', 'B1:D1', 'E1:E2']
-        excel.export_json_to_excel({
-          multiHeader,
-          header,
-          merges,
-          data
-        })
-        this.downloadLoading = false
-      })
-    },
-    formatJson(filterVal, jsonData) {
-      return jsonData.map(v => filterVal.map(j => {
-        if (j === 'timestamp') {
-          return parseTime(v[j])
-        } else {
-          return v[j]
-        }
-      }))
-    }
-  }
-}
-</script>

+ 0 - 107
src/views/excel/select-excel.vue

@@ -1,107 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:350px;" prefix-icon="el-icon-document" />
-    <el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">
-      Export Selected Items
-    </el-button>
-    <a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
-      <el-tag type="info">Documentation</el-tag>
-    </a>
-    <el-table
-      ref="multipleTable"
-      v-loading="listLoading"
-      :data="list"
-      element-loading-text="拼命加载中"
-      border
-      fit
-      highlight-current-row
-      @selection-change="handleSelectionChange"
-    >
-      <el-table-column type="selection" align="center" />
-      <el-table-column align="center" label="Id" width="95">
-        <template slot-scope="scope">
-          {{ scope.$index }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Title">
-        <template slot-scope="scope">
-          {{ scope.row.title }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Author" width="110" align="center">
-        <template slot-scope="scope">
-          <el-tag>{{ scope.row.author }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="Readings" width="115" align="center">
-        <template slot-scope="scope">
-          {{ scope.row.pageviews }}
-        </template>
-      </el-table-column>
-      <el-table-column align="center" label="PDate" width="220">
-        <template slot-scope="scope">
-          <i class="el-icon-time" />
-          <span>{{ scope.row.display_time }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-
-export default {
-  name: 'SelectExcel',
-  data() {
-    return {
-      list: null,
-      listLoading: true,
-      multipleSelection: [],
-      downloadLoading: false,
-      filename: ''
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      this.listLoading = true
-      fetchList(this.listQuery).then(response => {
-        this.list = response.data.items
-        this.listLoading = false
-      })
-    },
-    handleSelectionChange(val) {
-      this.multipleSelection = val
-    },
-    handleDownload() {
-      if (this.multipleSelection.length) {
-        this.downloadLoading = true
-        import('@/vendor/Export2Excel').then(excel => {
-          const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
-          const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
-          const list = this.multipleSelection
-          const data = this.formatJson(filterVal, list)
-          excel.export_json_to_excel({
-            header: tHeader,
-            data,
-            filename: this.filename
-          })
-          this.$refs.multipleTable.clearSelection()
-          this.downloadLoading = false
-        })
-      } else {
-        this.$message({
-          message: 'Please select at least one item',
-          type: 'warning'
-        })
-      }
-    },
-    formatJson(filterVal, jsonData) {
-      return jsonData.map(v => filterVal.map(j => v[j]))
-    }
-  }
-}
-</script>

+ 0 - 42
src/views/excel/upload-excel.vue

@@ -1,42 +0,0 @@
-<template>
-  <div class="app-container">
-    <upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
-    <el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;">
-      <el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" />
-    </el-table>
-  </div>
-</template>
-
-<script>
-import UploadExcelComponent from '@/components/UploadExcel/index.vue'
-
-export default {
-  name: 'UploadExcel',
-  components: { UploadExcelComponent },
-  data() {
-    return {
-      tableData: [],
-      tableHeader: []
-    }
-  },
-  methods: {
-    beforeUpload(file) {
-      const isLt1M = file.size / 1024 / 1024 < 1
-
-      if (isLt1M) {
-        return true
-      }
-
-      this.$message({
-        message: 'Please do not upload files larger than 1m in size.',
-        type: 'warning'
-      })
-      return false
-    },
-    handleSuccess({ results, header }) {
-      this.tableData = results
-      this.tableHeader = header
-    }
-  }
-}
-</script>

+ 53 - 53
src/views/login/index.vue

@@ -2,7 +2,7 @@
   <div class="login-container">
     <div class="login-nav">
       <div class="login-nav-img">
-        <img src="../../../public/images/nav-2.png" />
+        <img src="../../../public/images/nav-2.png">
       </div>
       <div class="login-nav-info">门禁设备管理平台</div>
 
@@ -21,49 +21,42 @@
           autocomplete="on"
         >
           <label>
-            <el-form-item
-              class="login-form-item"
-              prop="username"
-            >
-              <span><img src="../../../public/images/denglu.png" /></span>
+            <el-form-item class="login-form-item" prop="username">
+              <span><img src="../../../public/images/denglu.png"></span>
 
               <el-input
-                class="login-form-input"
-                v-model="loginForm.username"
                 ref="username"
+                v-model="loginForm.username"
+                class="login-form-input"
                 name="username"
                 placeholder="请输入您的账号"
-              ></el-input>
+              />
             </el-form-item>
           </label>
           <label>
-            <el-form-item
-              class="login-form-item"
-              prop="password"
-            >
-              <span><img src="../../../public/images/mima.png" /></span>
+            <el-form-item class="login-form-item" prop="password">
+              <span><img src="../../../public/images/mima.png"></span>
 
               <el-input
+                ref="password"
+                v-model="loginForm.password"
                 class="login-form-input"
                 type="password"
-                v-model="loginForm.password"
                 placeholder="请输入您的密码"
-                ref="password"
                 name="password"
                 autocomplete="on"
                 @keyup.native="checkCapslock"
                 @blur="capsTooltip = false"
                 @keyup.enter.native="handleLogin"
-              >
-              </el-input>
+              />
             </el-form-item>
           </label>
           <el-form-item>
             <el-button
               :loading="loading"
               type="primary"
-              @click.native.prevent="handleLogin"
               class="login-form-button"
+              @click.native.prevent="handleLogin"
             >登录</el-button>
           </el-form-item>
         </el-form>
@@ -74,38 +67,45 @@
 
 <script>
 export default {
-  name: "Login",
+  name: 'Login',
   data() {
     const validateUsername = (rule, value, callback) => {
       if (value.length < 5) {
-        callback(new Error("账号至少五位数"));
+        callback(new Error('账号至少五位数'))
       } else {
-        callback();
+        callback()
       }
-    };
+    }
     const validatePassword = (rule, value, callback) => {
-      if (value.length < 6) {
-        callback(new Error("密码至少六位数"));
+      const re =
+        /^(?![A-Za-z]+$)(?![A-Z\d]+$)(?![A-Z\W]+$)(?![a-z\d]+$)(?![a-z\W]+$)(?![\d\W]+$)\S{8,16}$/
+      const result = re.test(value)
+      if (!result) {
+        callback(
+          new Error(
+            '密码要求内含数字、大小写字母以及特殊字符中至少三种,长度8-16位'
+          )
+        )
       } else {
-        callback();
+        callback()
       }
-    };
+    }
     return {
       loginForm: {
-        username: "",
-        password: "",
+        username: '',
+        password: ''
       },
       rules: {
         username: [
-          { required: true, trigger: "blur", validator: validateUsername },
+          { required: true, trigger: 'blur', validator: validateUsername }
         ],
         password: [
-          { required: true, trigger: "blur", validator: validatePassword },
-        ],
+          { required: true, trigger: 'blur', validator: validatePassword }
+        ]
       },
       capsTooltip: false,
-      loading: false,
-    };
+      loading: false
+    }
   },
   // watch: {
   //   $route: {
@@ -123,10 +123,10 @@ export default {
   //   window.addEventListener('storage', this.afterQRScan)
   // },
   mounted() {
-    if (this.loginForm.username === "") {
-      this.$refs.username.focus();
-    } else if (this.loginForm.password === "") {
-      this.$refs.password.focus();
+    if (this.loginForm.username === '') {
+      this.$refs.username.focus()
+    } else if (this.loginForm.password === '') {
+      this.$refs.password.focus()
     }
   },
   // destroyed() {
@@ -134,32 +134,32 @@ export default {
   // },
   methods: {
     checkCapslock(e) {
-      const { key } = e;
-      this.capsTooltip = key && key.length === 1 && key >= "A" && key <= "Z";
+      const { key } = e
+      this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z'
     },
     handleLogin() {
       this.$refs.loginForm.validate((valid) => {
         if (valid) {
-          this.loading = true;
+          this.loading = true
           this.$store
-            .dispatch("user/login", this.loginForm)
+            .dispatch('user/login', this.loginForm)
             .then(() => {
               this.$router.push({
-                path: "/",
-              });
-              this.loading = false;
+                path: '/'
+              })
+              this.loading = false
             })
             .catch(() => {
-              this.loading = false;
-            });
+              this.loading = false
+            })
         } else {
-          console.log("error submit!!");
-          return false;
+          console.log('error submit!!')
+          return false
         }
-      });
-    },
-  },
-};
+      })
+    }
+  }
+}
 </script>
 
 <style scoped>

+ 0 - 7
src/views/nested/menu1/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 7
src/views/nested/menu1/menu1-1/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-1" type="success">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 7
src/views/nested/menu1/menu1-2/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2" type="success">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-2/menu1-2-1/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2-1" type="warning" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-2/menu1-2-2/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2-2" type="warning" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-3/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-3" type="success" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu2/index.vue

@@ -1,5 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 2" />
-  </div>
-</template>

ファイルの差分が大きいため隠しています
+ 0 - 58
src/views/pdf/content.js


+ 0 - 201
src/views/pdf/download.vue

@@ -1,201 +0,0 @@
-<template>
-  <div v-loading.fullscreen.lock="fullscreenLoading" class="main-article" element-loading-text="Efforts to generate PDF">
-    <div class="article__heading">
-      <div class="article__heading__title">
-        {{ article.title }}
-      </div>
-    </div>
-    <div style="color: #ccc;">
-      This article is from Evan You on <a target="_blank" href="https://medium.com/the-vue-point/plans-for-the-next-iteration-of-vue-js-777ffea6fabf">medium</a>
-    </div>
-    <div ref="content" class="node-article-content" v-html="article.content" />
-  </div>
-</template>
-
-<script>
-
-export default {
-  data() {
-    return {
-      article: '',
-      fullscreenLoading: true
-    }
-  },
-  mounted() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      import('./content.js').then(data => {
-        const { title } = data.default
-        document.title = title
-        this.article = data.default
-        setTimeout(() => {
-          this.fullscreenLoading = false
-          this.$nextTick(() => {
-            window.print()
-          })
-        }, 3000)
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss">
-@mixin clearfix {
-  &:before {
-    display: table;
-    content: '';
-    clear: both;
-  }
-
-  &:after {
-    display: table;
-    content: '';
-    clear: both;
-  }
-}
-
-.main-article {
-  padding: 20px;
-  margin: 0 auto;
-  display: block;
-  width: 740px;
-  background: #fff;
-}
-
-.article__heading {
-  position: relative;
-  padding: 0 0 20px;
-  overflow: hidden;
-}
-
-.article__heading__title {
-  display: block;
-  display: -webkit-box;
-  -webkit-box-orient: vertical;
-  -webkit-line-clamp: 2;
-  line-clamp: 2;
-  word-wrap: break-word;
-  overflow-wrap: break-word;
-  font-size: 32px;
-  line-height: 48px;
-  font-weight: 600;
-  color: #333;
-  overflow: hidden;
-}
-
-.node-article-content {
-  margin: 20px 0 0;
-  @include clearfix;
-  font-size: 16px;
-  color: #333;
-  letter-spacing: 0.5px;
-  line-height: 28px;
-  margin-bottom: 30px;
-  font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif;
-
-  &> :last-child {
-    margin-bottom: 0;
-  }
-
-  b,
-  strong {
-    font-weight: inherit;
-    font-weight: bolder;
-  }
-
-  img {
-    max-width: 100%;
-    display: block;
-    margin: 0 auto;
-  }
-
-  p {
-    font-weight: 400;
-    font-style: normal;
-    font-size: 21px;
-    line-height: 1.58;
-    letter-spacing: -.003em;
-
-  }
-
-  ul {
-    margin-bottom: 30px;
-  }
-
-  li {
-    --x-height-multiplier: 0.375;
-    --baseline-multiplier: 0.17;
-
-    letter-spacing: .01rem;
-    font-weight: 400;
-    font-style: normal;
-    font-size: 21px;
-    line-height: 1.58;
-    letter-spacing: -.003em;
-    margin-left: 30px;
-    margin-bottom: 14px;
-  }
-
-  a {
-    text-decoration: none;
-    background-repeat: repeat-x;
-    background-image: linear-gradient(to right, rgba(0, 0, 0, .84) 100%, rgba(0, 0, 0, 0) 0);
-    background-size: 1px 1px;
-    background-position: 0 calc(1em + 1px);
-    padding: 0 6px;
-  }
-
-  code {
-    background: rgba(0, 0, 0, .05);
-    padding: 3px 4px;
-    margin: 0 2px;
-    font-size: 16px;
-    display: inline-block;
-  }
-
-  img {
-    border: 0;
-  }
-
-  /* 解决 IE6-7 图片缩放锯齿问题 */
-  img {
-    -ms-interpolation-mode: bicubic;
-  }
-
-  blockquote {
-    --x-height-multiplier: 0.375;
-    --baseline-multiplier: 0.17;
-    font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif;
-    letter-spacing: .01rem;
-    font-weight: 400;
-    font-style: italic;
-    font-size: 21px;
-    line-height: 1.58;
-    letter-spacing: -.003em;
-    border-left: 3px solid rgba(0, 0, 0, .84);
-    padding-left: 20px;
-    margin-left: -23px;
-    padding-bottom: 2px;
-  }
-
-  a {
-    text-decoration: none;
-  }
-
-  h2,
-  h3,
-  h4 {
-    font-size: 34px;
-    line-height: 1.15;
-    letter-spacing: -.015em;
-    margin: 53px 0 0;
-  }
-
-  h4 {
-    font-size: 26px;
-  }
-}
-</style>

+ 0 - 13
src/views/pdf/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="app-container">
-    <aside style="margin-top:15px;">
-      Here we use window.print() to implement the feature of downloading PDF.
-    </aside>
-    <router-link target="_blank" to="/pdf/download">
-      <el-button type="primary">
-        Click to download PDF
-      </el-button>
-    </router-link>
-  </div>
-</template>
-

+ 0 - 41
src/views/qiniu/upload.vue

@@ -1,41 +0,0 @@
-<template>
-  <el-upload :data="dataObj" :multiple="true" :before-upload="beforeUpload" action="https://upload.qbox.me" drag>
-    <i class="el-icon-upload" />
-    <div class="el-upload__text">
-      将文件拖到此处,或<em>点击上传</em>
-    </div>
-  </el-upload>
-</template>
-
-<script>
-import { getToken } from '@/api/qiniu'
-// 获取七牛token 后端通过Access Key,Secret Key,bucket等生成token
-// 七牛官方sdk https://developer.qiniu.com/sdk#official-sdk
-
-export default {
-  data() {
-    return {
-      dataObj: { token: '', key: '' },
-      image_uri: [],
-      fileList: []
-    }
-  },
-  methods: {
-    beforeUpload() {
-      const _self = this
-      return new Promise((resolve, reject) => {
-        getToken().then(response => {
-          const key = response.data.qiniu_key
-          const token = response.data.qiniu_token
-          _self._data.dataObj.token = token
-          _self._data.dataObj.key = key
-          resolve(true)
-        }).catch(err => {
-          console.log(err)
-          reject(false)
-        })
-      })
-    }
-  }
-}
-</script>

+ 0 - 103
src/views/tab/components/TabPane.vue

@@ -1,103 +0,0 @@
-<template>
-  <el-table :data="list" border fit highlight-current-row style="width: 100%">
-    <el-table-column
-      v-loading="loading"
-      align="center"
-      label="ID"
-      width="65"
-      element-loading-text="请给我点时间!"
-    >
-      <template slot-scope="scope">
-        <span>{{ scope.row.id }}</span>
-      </template>
-    </el-table-column>
-
-    <el-table-column width="180px" align="center" label="Date">
-      <template slot-scope="scope">
-        <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-      </template>
-    </el-table-column>
-
-    <el-table-column min-width="300px" label="Title">
-      <template slot-scope="{row}">
-        <span>{{ row.title }}</span>
-        <el-tag>{{ row.type }}</el-tag>
-      </template>
-    </el-table-column>
-
-    <el-table-column width="110px" align="center" label="Author">
-      <template slot-scope="scope">
-        <span>{{ scope.row.author }}</span>
-      </template>
-    </el-table-column>
-
-    <el-table-column width="120px" label="Importance">
-      <template slot-scope="scope">
-        <svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" />
-      </template>
-    </el-table-column>
-
-    <el-table-column align="center" label="Readings" width="95">
-      <template slot-scope="scope">
-        <span>{{ scope.row.pageviews }}</span>
-      </template>
-    </el-table-column>
-
-    <el-table-column class-name="status-col" label="Status" width="110">
-      <template slot-scope="{row}">
-        <el-tag :type="row.status | statusFilter">
-          {{ row.status }}
-        </el-tag>
-      </template>
-    </el-table-column>
-  </el-table>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-
-export default {
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'info',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  props: {
-    type: {
-      type: String,
-      default: 'CN'
-    }
-  },
-  data() {
-    return {
-      list: null,
-      listQuery: {
-        page: 1,
-        limit: 5,
-        type: this.type,
-        sort: '+id'
-      },
-      loading: false
-    }
-  },
-  created() {
-    this.getList()
-  },
-  methods: {
-    getList() {
-      this.loading = true
-      this.$emit('create') // for test
-      fetchList(this.listQuery).then(response => {
-        this.list = response.data.items
-        this.loading = false
-      })
-    }
-  }
-}
-</script>
-

+ 0 - 57
src/views/tab/index.vue

@@ -1,57 +0,0 @@
-<template>
-  <div class="tab-container">
-    <el-tag>mounted times :{{ createdTimes }}</el-tag>
-    <el-alert :closable="false" style="width:200px;display:inline-block;vertical-align: middle;margin-left:30px;" title="Tab with keep-alive" type="success" />
-    <el-tabs v-model="activeName" style="margin-top:15px;" type="border-card">
-      <el-tab-pane v-for="item in tabMapOptions" :key="item.key" :label="item.label" :name="item.key">
-        <keep-alive>
-          <tab-pane v-if="activeName==item.key" :type="item.key" @create="showCreatedTimes" />
-        </keep-alive>
-      </el-tab-pane>
-    </el-tabs>
-  </div>
-</template>
-
-<script>
-import TabPane from './components/TabPane'
-
-export default {
-  name: 'Tab',
-  components: { TabPane },
-  data() {
-    return {
-      tabMapOptions: [
-        { label: 'China', key: 'CN' },
-        { label: 'USA', key: 'US' },
-        { label: 'Japan', key: 'JP' },
-        { label: 'Eurozone', key: 'EU' }
-      ],
-      activeName: 'CN',
-      createdTimes: 0
-    }
-  },
-  watch: {
-    activeName(val) {
-      this.$router.push(`${this.$route.path}?tab=${val}`)
-    }
-  },
-  created() {
-    // init the default selected tab
-    const tab = this.$route.query.tab
-    if (tab) {
-      this.activeName = tab
-    }
-  },
-  methods: {
-    showCreatedTimes() {
-      this.createdTimes = this.createdTimes + 1
-    }
-  }
-}
-</script>
-
-<style scoped>
-  .tab-container {
-    margin: 30px;
-  }
-</style>

+ 0 - 379
src/views/table/complex-table.vue

@@ -1,379 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="filter-container">
-      <el-input v-model="listQuery.title" placeholder="Title" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
-      <el-select v-model="listQuery.importance" placeholder="Imp" clearable style="width: 90px" class="filter-item">
-        <el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item" />
-      </el-select>
-      <el-select v-model="listQuery.type" placeholder="Type" clearable class="filter-item" style="width: 130px">
-        <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key" />
-      </el-select>
-      <el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
-        <el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
-      </el-select>
-      <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
-        Search
-      </el-button>
-      <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
-        Add
-      </el-button>
-      <el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
-        Export
-      </el-button>
-      <el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
-        reviewer
-      </el-checkbox>
-    </div>
-
-    <el-table
-      :key="tableKey"
-      v-loading="listLoading"
-      :data="list"
-      border
-      fit
-      highlight-current-row
-      style="width: 100%;"
-      @sort-change="sortChange"
-    >
-      <el-table-column label="ID" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')">
-        <template slot-scope="{row}">
-          <span>{{ row.id }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Date" width="150px" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Title" min-width="150px">
-        <template slot-scope="{row}">
-          <span class="link-type" @click="handleUpdate(row)">{{ row.title }}</span>
-          <el-tag>{{ row.type | typeFilter }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="Author" width="110px" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.author }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column v-if="showReviewer" label="Reviewer" width="110px" align="center">
-        <template slot-scope="{row}">
-          <span style="color:red;">{{ row.reviewer }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Imp" width="80px">
-        <template slot-scope="{row}">
-          <svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
-        </template>
-      </el-table-column>
-      <el-table-column label="Readings" align="center" width="95">
-        <template slot-scope="{row}">
-          <span v-if="row.pageviews" class="link-type" @click="handleFetchPv(row.pageviews)">{{ row.pageviews }}</span>
-          <span v-else>0</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Status" class-name="status-col" width="100">
-        <template slot-scope="{row}">
-          <el-tag :type="row.status | statusFilter">
-            {{ row.status }}
-          </el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="Actions" align="center" width="230" class-name="small-padding fixed-width">
-        <template slot-scope="{row,$index}">
-          <el-button type="primary" size="mini" @click="handleUpdate(row)">
-            Edit
-          </el-button>
-          <el-button v-if="row.status!='published'" size="mini" type="success" @click="handleModifyStatus(row,'published')">
-            Publish
-          </el-button>
-          <el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')">
-            Draft
-          </el-button>
-          <el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)">
-            Delete
-          </el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
-
-    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
-      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
-        <el-form-item label="Type" prop="type">
-          <el-select v-model="temp.type" class="filter-item" placeholder="Please select">
-            <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="Date" prop="timestamp">
-          <el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" />
-        </el-form-item>
-        <el-form-item label="Title" prop="title">
-          <el-input v-model="temp.title" />
-        </el-form-item>
-        <el-form-item label="Status">
-          <el-select v-model="temp.status" class="filter-item" placeholder="Please select">
-            <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="Imp">
-          <el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" />
-        </el-form-item>
-        <el-form-item label="Remark">
-          <el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" />
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button @click="dialogFormVisible = false">
-          Cancel
-        </el-button>
-        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
-          Confirm
-        </el-button>
-      </div>
-    </el-dialog>
-
-    <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
-      <el-table :data="pvData" border fit highlight-current-row style="width: 100%">
-        <el-table-column prop="key" label="Channel" />
-        <el-table-column prop="pv" label="Pv" />
-      </el-table>
-      <span slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="dialogPvVisible = false">Confirm</el-button>
-      </span>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
-import waves from '@/directive/waves' // waves directive
-import { parseTime } from '@/utils'
-import Pagination from '@/components/Pagination' // secondary package based on el-pagination
-
-const calendarTypeOptions = [
-  { key: 'CN', display_name: 'China' },
-  { key: 'US', display_name: 'USA' },
-  { key: 'JP', display_name: 'Japan' },
-  { key: 'EU', display_name: 'Eurozone' }
-]
-
-// arr to obj, such as { CN : "China", US : "USA" }
-const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
-  acc[cur.key] = cur.display_name
-  return acc
-}, {})
-
-export default {
-  name: 'ComplexTable',
-  components: { Pagination },
-  directives: { waves },
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'info',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    },
-    typeFilter(type) {
-      return calendarTypeKeyValue[type]
-    }
-  },
-  data() {
-    return {
-      tableKey: 0,
-      list: null,
-      total: 0,
-      listLoading: true,
-      listQuery: {
-        page: 1,
-        limit: 20,
-        importance: undefined,
-        title: undefined,
-        type: undefined,
-        sort: '+id'
-      },
-      importanceOptions: [1, 2, 3],
-      calendarTypeOptions,
-      sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
-      statusOptions: ['published', 'draft', 'deleted'],
-      showReviewer: false,
-      temp: {
-        id: undefined,
-        importance: 1,
-        remark: '',
-        timestamp: new Date(),
-        title: '',
-        type: '',
-        status: 'published'
-      },
-      dialogFormVisible: false,
-      dialogStatus: '',
-      textMap: {
-        update: 'Edit',
-        create: 'Create'
-      },
-      dialogPvVisible: false,
-      pvData: [],
-      rules: {
-        type: [{ required: true, message: 'type is required', trigger: 'change' }],
-        timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
-        title: [{ required: true, message: 'title is required', trigger: 'blur' }]
-      },
-      downloadLoading: false
-    }
-  },
-  created() {
-    this.getList()
-  },
-  methods: {
-    getList() {
-      this.listLoading = true
-      fetchList(this.listQuery).then(response => {
-        this.list = response.data.items
-        this.total = response.data.total
-
-        // Just to simulate the time of the request
-        setTimeout(() => {
-          this.listLoading = false
-        }, 1.5 * 1000)
-      })
-    },
-    handleFilter() {
-      this.listQuery.page = 1
-      this.getList()
-    },
-    // handleModifyStatus(row, status) {
-    //   this.$message({
-    //     message: '操作Success',
-    //     type: 'success'
-    //   })
-    //   row.status = status
-    // },
-    sortChange(data) {
-      const { prop, order } = data
-      if (prop === 'id') {
-        this.sortByID(order)
-      }
-    },
-    sortByID(order) {
-      if (order === 'ascending') {
-        this.listQuery.sort = '+id'
-      } else {
-        this.listQuery.sort = '-id'
-      }
-      this.handleFilter()
-    },
-    resetTemp() {
-      this.temp = {
-        id: undefined,
-        importance: 1,
-        remark: '',
-        timestamp: new Date(),
-        title: '',
-        status: 'published',
-        type: ''
-      }
-    },
-    handleCreate() {
-      this.resetTemp()
-      this.dialogStatus = 'create'
-      this.dialogFormVisible = true
-      this.$nextTick(() => {
-        this.$refs['dataForm'].clearValidate()
-      })
-    },
-    createData() {
-      this.$refs['dataForm'].validate((valid) => {
-        if (valid) {
-          this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
-          this.temp.author = 'vue-element-admin'
-          createArticle(this.temp).then(() => {
-            this.list.unshift(this.temp)
-            this.dialogFormVisible = false
-            this.$notify({
-              title: 'Success',
-              message: 'Created Successfully',
-              type: 'success',
-              duration: 2000
-            })
-          })
-        }
-      })
-    },
-    handleUpdate(row) {
-      this.temp = Object.assign({}, row) // copy obj
-      this.temp.timestamp = new Date(this.temp.timestamp)
-      this.dialogStatus = 'update'
-      this.dialogFormVisible = true
-      this.$nextTick(() => {
-        this.$refs['dataForm'].clearValidate()
-      })
-    },
-    updateData() {
-      this.$refs['dataForm'].validate((valid) => {
-        if (valid) {
-          const tempData = Object.assign({}, this.temp)
-          tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
-          updateArticle(tempData).then(() => {
-            const index = this.list.findIndex(v => v.id === this.temp.id)
-            this.list.splice(index, 1, this.temp)
-            this.dialogFormVisible = false
-            this.$notify({
-              title: 'Success',
-              message: 'Update Successfully',
-              type: 'success',
-              duration: 2000
-            })
-          })
-        }
-      })
-    },
-    handleDelete(row, index) {
-      this.$notify({
-        title: 'Success',
-        message: 'Delete Successfully',
-        type: 'success',
-        duration: 2000
-      })
-      this.list.splice(index, 1)
-    },
-    handleFetchPv(pv) {
-      fetchPv(pv).then(response => {
-        this.pvData = response.data.pvData
-        this.dialogPvVisible = true
-      })
-    },
-    handleDownload() {
-      this.downloadLoading = true
-      import('@/vendor/Export2Excel').then(excel => {
-        const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
-        const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
-        const data = this.formatJson(filterVal)
-        excel.export_json_to_excel({
-          header: tHeader,
-          data,
-          filename: 'table-list'
-        })
-        this.downloadLoading = false
-      })
-    },
-    formatJson(filterVal) {
-      return this.list.map(v => filterVal.map(j => {
-        if (j === 'timestamp') {
-          return parseTime(v[j])
-        } else {
-          return v[j]
-        }
-      }))
-    },
-    getSortClass: function(key) {
-      const sort = this.listQuery.sort
-      return sort === `+${key}` ? 'ascending' : 'descending'
-    }
-  }
-}
-</script>

+ 0 - 153
src/views/table/drag-table.vue

@@ -1,153 +0,0 @@
-<template>
-  <div class="app-container">
-    <!-- Note that row-key is necessary to get a correct row order. -->
-    <el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
-      <el-table-column align="center" label="ID" width="65">
-        <template slot-scope="{row}">
-          <span>{{ row.id }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="180px" align="center" label="Date">
-        <template slot-scope="{row}">
-          <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column min-width="300px" label="Title">
-        <template slot-scope="{row}">
-          <span>{{ row.title }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="110px" align="center" label="Author">
-        <template slot-scope="{row}">
-          <span>{{ row.author }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="100px" label="Importance">
-        <template slot-scope="{row}">
-          <svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="icon-star" />
-        </template>
-      </el-table-column>
-
-      <el-table-column align="center" label="Readings" width="95">
-        <template slot-scope="{row}">
-          <span>{{ row.pageviews }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column class-name="status-col" label="Status" width="110">
-        <template slot-scope="{row}">
-          <el-tag :type="row.status | statusFilter">
-            {{ row.status }}
-          </el-tag>
-        </template>
-      </el-table-column>
-
-      <el-table-column align="center" label="Drag" width="80">
-        <template slot-scope="{}">
-          <svg-icon class="drag-handler" icon-class="drag" />
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="show-d">
-      <el-tag>The default order :</el-tag> {{ oldList }}
-    </div>
-    <div class="show-d">
-      <el-tag>The after dragging order :</el-tag> {{ newList }}
-    </div>
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-import Sortable from 'sortablejs'
-
-export default {
-  name: 'DragTable',
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'info',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  data() {
-    return {
-      list: null,
-      total: null,
-      listLoading: true,
-      listQuery: {
-        page: 1,
-        limit: 10
-      },
-      sortable: null,
-      oldList: [],
-      newList: []
-    }
-  },
-  created() {
-    this.getList()
-  },
-  methods: {
-    async getList() {
-      this.listLoading = true
-      const { data } = await fetchList(this.listQuery)
-      this.list = data.items
-      this.total = data.total
-      this.listLoading = false
-      this.oldList = this.list.map(v => v.id)
-      this.newList = this.oldList.slice()
-      this.$nextTick(() => {
-        this.setSort()
-      })
-    },
-    setSort() {
-      const el = this.$refs.dragTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
-      this.sortable = Sortable.create(el, {
-        ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
-        setData: function(dataTransfer) {
-          // to avoid Firefox bug
-          // Detail see : https://github.com/RubaXa/Sortable/issues/1012
-          dataTransfer.setData('Text', '')
-        },
-        onEnd: evt => {
-          const targetRow = this.list.splice(evt.oldIndex, 1)[0]
-          this.list.splice(evt.newIndex, 0, targetRow)
-
-          // for show the changes, you can delete in you code
-          const tempIndex = this.newList.splice(evt.oldIndex, 1)[0]
-          this.newList.splice(evt.newIndex, 0, tempIndex)
-        }
-      })
-    }
-  }
-}
-</script>
-
-<style>
-.sortable-ghost{
-  opacity: .8;
-  color: #fff!important;
-  background: #42b983!important;
-}
-</style>
-
-<style scoped>
-.icon-star{
-  margin-right:2px;
-}
-.drag-handler{
-  width: 20px;
-  height: 20px;
-  cursor: pointer;
-}
-.show-d{
-  margin-top: 15px;
-}
-</style>

+ 0 - 62
src/views/table/dynamic-table/components/FixedThead.vue

@@ -1,62 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="filter-container">
-      <el-checkbox-group v-model="checkboxVal">
-        <el-checkbox label="apple">
-          apple
-        </el-checkbox>
-        <el-checkbox label="banana">
-          banana
-        </el-checkbox>
-        <el-checkbox label="orange">
-          orange
-        </el-checkbox>
-      </el-checkbox-group>
-    </div>
-
-    <el-table :key="key" :data="tableData" border fit highlight-current-row style="width: 100%">
-      <el-table-column prop="name" label="fruitName" width="180" />
-      <el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit">
-        <template slot-scope="scope">
-          {{ scope.row[fruit] }}
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-const defaultFormThead = ['apple', 'banana']
-
-export default {
-  data() {
-    return {
-      tableData: [
-        {
-          name: 'fruit-1',
-          apple: 'apple-10',
-          banana: 'banana-10',
-          orange: 'orange-10'
-        },
-        {
-          name: 'fruit-2',
-          apple: 'apple-20',
-          banana: 'banana-20',
-          orange: 'orange-20'
-        }
-      ],
-      key: 1, // table key
-      formTheadOptions: ['apple', 'banana', 'orange'],
-      checkboxVal: defaultFormThead, // checkboxVal
-      formThead: defaultFormThead // 默认表头 Default header
-    }
-  },
-  watch: {
-    checkboxVal(valArr) {
-      this.formThead = this.formTheadOptions.filter(i => valArr.indexOf(i) >= 0)
-      this.key = this.key + 1// 为了保证table 每次都会重渲 In order to ensure the table will be re-rendered each time
-    }
-  }
-}
-</script>
-

+ 0 - 50
src/views/table/dynamic-table/components/UnfixedThead.vue

@@ -1,50 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="filter-container">
-      <el-checkbox-group v-model="formThead">
-        <el-checkbox label="apple">
-          apple
-        </el-checkbox>
-        <el-checkbox label="banana">
-          banana
-        </el-checkbox>
-        <el-checkbox label="orange">
-          orange
-        </el-checkbox>
-      </el-checkbox-group>
-    </div>
-
-    <el-table :data="tableData" border fit highlight-current-row style="width: 100%">
-      <el-table-column prop="name" label="fruitName" width="180" />
-      <el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit">
-        <template slot-scope="scope">
-          {{ scope.row[fruit] }}
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      tableData: [
-        {
-          name: 'fruit-1',
-          apple: 'apple-10',
-          banana: 'banana-10',
-          orange: 'orange-10'
-        },
-        {
-          name: 'fruit-2',
-          apple: 'apple-20',
-          banana: 'banana-20',
-          orange: 'orange-20'
-        }
-      ],
-      formThead: ['apple', 'banana']
-    }
-  }
-}
-</script>

+ 0 - 24
src/views/table/dynamic-table/index.vue

@@ -1,24 +0,0 @@
-<template>
-  <div class="app-container">
-    <div style="margin:0 0 5px 20px">
-      Fixed header, sorted by header order,
-    </div>
-    <fixed-thead />
-
-    <div style="margin:30px 0 5px 20px">
-      Not fixed header, sorted by click order
-    </div>
-    <unfixed-thead />
-  </div>
-</template>
-
-<script>
-import FixedThead from './components/FixedThead'
-import UnfixedThead from './components/UnfixedThead'
-
-export default {
-  name: 'DynamicTable',
-  components: { FixedThead, UnfixedThead }
-}
-</script>
-

+ 0 - 149
src/views/table/inline-edit-table.vue

@@ -1,149 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
-      <el-table-column align="center" label="ID" width="80">
-        <template slot-scope="{row}">
-          <span>{{ row.id }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="180px" align="center" label="Date">
-        <template slot-scope="{row}">
-          <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="120px" align="center" label="Author">
-        <template slot-scope="{row}">
-          <span>{{ row.author }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column width="100px" label="Importance">
-        <template slot-scope="{row}">
-          <svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
-        </template>
-      </el-table-column>
-
-      <el-table-column class-name="status-col" label="Status" width="110">
-        <template slot-scope="{row}">
-          <el-tag :type="row.status | statusFilter">
-            {{ row.status }}
-          </el-tag>
-        </template>
-      </el-table-column>
-
-      <el-table-column min-width="300px" label="Title">
-        <template slot-scope="{row}">
-          <template v-if="row.edit">
-            <el-input v-model="row.title" class="edit-input" size="small" />
-            <el-button
-              class="cancel-btn"
-              size="small"
-              icon="el-icon-refresh"
-              type="warning"
-              @click="cancelEdit(row)"
-            >
-              cancel
-            </el-button>
-          </template>
-          <span v-else>{{ row.title }}</span>
-        </template>
-      </el-table-column>
-
-      <el-table-column align="center" label="Actions" width="120">
-        <template slot-scope="{row}">
-          <el-button
-            v-if="row.edit"
-            type="success"
-            size="small"
-            icon="el-icon-circle-check-outline"
-            @click="confirmEdit(row)"
-          >
-            Ok
-          </el-button>
-          <el-button
-            v-else
-            type="primary"
-            size="small"
-            icon="el-icon-edit"
-            @click="row.edit=!row.edit"
-          >
-            Edit
-          </el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-import { fetchList } from '@/api/article'
-
-export default {
-  name: 'InlineEditTable',
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'info',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  data() {
-    return {
-      list: null,
-      listLoading: true,
-      listQuery: {
-        page: 1,
-        limit: 10
-      }
-    }
-  },
-  created() {
-    this.getList()
-  },
-  methods: {
-    async getList() {
-      this.listLoading = true
-      const { data } = await fetchList(this.listQuery)
-      const items = data.items
-      this.list = items.map(v => {
-        this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
-        v.originalTitle = v.title //  will be used when user click the cancel botton
-        return v
-      })
-      this.listLoading = false
-    },
-    cancelEdit(row) {
-      row.title = row.originalTitle
-      row.edit = false
-      this.$message({
-        message: 'The title has been restored to the original value',
-        type: 'warning'
-      })
-    },
-    confirmEdit(row) {
-      row.edit = false
-      row.originalTitle = row.title
-      this.$message({
-        message: 'The title has been edited',
-        type: 'success'
-      })
-    }
-  }
-}
-</script>
-
-<style scoped>
-.edit-input {
-  padding-right: 100px;
-}
-.cancel-btn {
-  position: absolute;
-  right: 15px;
-  top: 10px;
-}
-</style>

+ 116 - 109
src/views/user/index.vue

@@ -3,7 +3,7 @@
     <!-- 头部区域 -->
     <div class="head">
       <div class="head-img">
-        <img src="../../../public/images/user-1.png" />
+        <img src="../../../public/images/user-1.png">
       </div>
       <div class="head-info">账号管理</div>
     </div>
@@ -19,22 +19,26 @@
           clearable
           @clear="getList"
           @keyup.enter.native="handleFilter"
-        >
-        </el-input>
+        />
       </div>
 
       <div class="input-serch">
         <el-row>
-          <el-button size="small" type="primary" @click="handleFilter"
-            >搜索</el-button
-          >
+          <el-button
+            size="small"
+            type="primary"
+            @click="handleFilter"
+          >搜索</el-button>
         </el-row>
       </div>
 
       <div class="input-add">
         <el-row>
-          <el-button type="primary" size="small" @click="handleCreate"
-            ><img src="../../../public/images/img-3.png" />添加
+          <el-button
+            type="primary"
+            size="small"
+            @click="handleCreate"
+          ><img src="../../../public/images/img-3.png">添加
           </el-button>
         </el-row>
       </div>
@@ -57,16 +61,17 @@
 
         <el-table-column label="操作" align="center">
           <template slot-scope="{ row, $index }">
-            <el-button type="text" size="small" @click="handleUpdate(row)"
-              >编辑</el-button
-            >
             <el-button
-              @click="handleDelete(row, $index)"
+              type="text"
+              size="small"
+              @click="handleUpdate(row)"
+            >编辑</el-button>
+            <el-button
               type="text"
               size="small"
               class="button"
-              ><img src="../../../public/images/img-2.png" />删除</el-button
-            >
+              @click="handleDelete(row, $index)"
+            ><img src="../../../public/images/img-2.png">删除</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -105,8 +110,7 @@
               autocomplete="off"
               placeholder="请输入账号"
               style="width: 110%"
-            >
-            </el-input>
+            />
           </el-col>
         </el-form-item>
 
@@ -122,8 +126,7 @@
               autocomplete="off"
               placeholder="请输入昵称"
               style="width: 110%"
-            >
-            </el-input>
+            />
           </el-col>
         </el-form-item>
 
@@ -140,8 +143,7 @@
               type="password"
               placeholder="请输入密码"
               style="width: 110%"
-            >
-            </el-input>
+            />
           </el-col>
         </el-form-item>
       </el-form>
@@ -149,8 +151,7 @@
         <el-button
           type="primary"
           @click="dialogStatus === 'create' ? createData() : updateData()"
-          >确 定</el-button
-        >
+        >确 定</el-button>
         <el-button @click="dialogFormVisible = false">取 消</el-button>
       </span>
     </el-dialog>
@@ -158,175 +159,181 @@
 </template>
 
 <script>
-import Pagination from "@/components/Pagination";
+import Pagination from '@/components/Pagination'
 import {
   createAdmin,
   updateAdmin,
   deleteAdmin,
   fetchList,
-  searchList,
-} from "@/api/getuser";
+  searchList
+} from '@/api/getuser'
 
 export default {
   components: {
-    Pagination,
+    Pagination
   },
   data() {
     const validateUsername = (rule, value, callback) => {
       if (value.length < 5) {
-        callback(new Error("账号至少五位数"));
+        callback(new Error('账号至少五位数'))
       } else {
-        callback();
+        callback()
       }
-    };
+    }
     const validatePassword = (rule, value, callback) => {
-      if (value.length < 6) {
-        callback(new Error("密码至少六位数"));
+      const re =
+        /^(?![A-Za-z]+$)(?![A-Z\d]+$)(?![A-Z\W]+$)(?![a-z\d]+$)(?![a-z\W]+$)(?![\d\W]+$)\S{8,16}$/
+      const result = re.test(value)
+      if (!result) {
+        callback(
+          new Error(
+            '密码要求内含数字、大小写字母以及特殊字符中至少三种,长度8-16位'
+          )
+        )
       } else {
-        callback();
+        callback()
       }
-    };
+    }
     return {
       list: [],
       total: 0,
       listQuery: {
         page: 1,
         limit: 8,
-        name: "",
-        nickname: "",
-        password: "",
+        name: '',
+        nickname: '',
+        password: ''
       },
       temp: {
         id: undefined,
-        name: "",
-        nickname: "",
-        password: "",
+        name: '',
+        nickname: '',
+        password: ''
       },
       dialogFormVisible: false,
-      dialogStatus: "",
+      dialogStatus: '',
       textMap: {
-        update: "编辑账号信息",
-        create: "添加账号",
+        update: '编辑账号信息',
+        create: '添加账号'
       },
       rules: {
         name: [
           {
             required: true,
-            message: "账号至少五位数",
-            trigger: "change",
-            validator: validateUsername,
-          },
+            message: '账号至少五位数',
+            trigger: 'change',
+            validator: validateUsername
+          }
         ],
         nickname: [
           {
             required: true,
-            message: "请输入昵称",
-            trigger: "change",
-          },
+            message: '请输入昵称',
+            trigger: 'change'
+          }
         ],
         password: [
           {
             required: true,
-            message: "密码至少六位数",
-            trigger: "change",
-            validator: validatePassword,
-          },
-        ],
-      },
-    };
+            trigger: 'change',
+            validator: validatePassword
+          }
+        ]
+      }
+    }
   },
   created() {
-    this.getList();
+    this.getList()
   },
   methods: {
     getList() {
       fetchList(this.listQuery).then((response) => {
-        this.list = response.data;
-        this.total = response.total;
-      });
+        this.list = response.data
+        this.total = response.total
+      })
     },
     handleDelete(row, index) {
-      if (confirm("是否删除?")) {
+      if (confirm('是否删除?')) {
         deleteAdmin({ id: row.id }).then(() => {
           this.$notify({
-            title: "删除成功",
-            type: "success",
-            duration: 2000,
-          });
-          this.list.splice(index, 1);
-        });
+            title: '删除成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.list.splice(index, 1)
+        })
       }
     },
     resetTemp() {
       this.temp = {
         id: undefined,
-        name: "",
-        nickname: "",
-        password: "",
-      };
+        name: '',
+        nickname: '',
+        password: ''
+      }
     },
     handleCreate() {
-      this.resetTemp();
-      this.dialogStatus = "create";
-      this.dialogFormVisible = true;
+      this.resetTemp()
+      this.dialogStatus = 'create'
+      this.dialogFormVisible = true
       this.$nextTick(() => {
-        this.$refs["dataForm"].clearValidate();
-      });
+        this.$refs['dataForm'].clearValidate()
+      })
     },
     createData() {
-      this.$refs["dataForm"].validate((valid) => {
+      this.$refs['dataForm'].validate((valid) => {
         if (valid) {
           createAdmin(this.temp).then(() => {
-            this.list.unshift(this.temp);
-            this.dialogFormVisible = false;
+            this.list.unshift(this.temp)
+            this.dialogFormVisible = false
             this.$notify({
-              title: "添加成功",
-              type: "success",
-              duration: 2000,
-            });
-          });
+              title: '添加成功',
+              type: 'success',
+              duration: 2000
+            })
+          })
         }
-      });
+      })
     },
     handleUpdate(row) {
-      this.temp = Object.assign({}, row); // copy obj
-      this.temp.password = "";
-      this.dialogStatus = "update";
-      this.dialogFormVisible = true;
+      this.temp = Object.assign({}, row) // copy obj
+      this.temp.password = ''
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
       this.$nextTick(() => {
-        this.$refs["dataForm"].clearValidate();
-      });
+        this.$refs['dataForm'].clearValidate()
+      })
     },
     updateData() {
-      this.$refs["dataForm"].validate((valid) => {
+      this.$refs['dataForm'].validate((valid) => {
         if (valid) {
-          const tempData = Object.assign({}, this.temp);
+          const tempData = Object.assign({}, this.temp)
 
           updateAdmin(tempData).then(() => {
-            const index = this.list.findIndex((v) => v.id === this.temp.id);
-            this.list.splice(index, 1, this.temp);
-            this.dialogFormVisible = false;
+            const index = this.list.findIndex((v) => v.id === this.temp.id)
+            this.list.splice(index, 1, this.temp)
+            this.dialogFormVisible = false
             this.$notify({
-              title: "编辑成功",
-              type: "success",
-              duration: 2000,
-            });
-          });
+              title: '编辑成功',
+              type: 'success',
+              duration: 2000
+            })
+          })
         }
-      });
+      })
     },
     handleFilter() {
       if (!this.listQuery.name) {
-        alert("请输入账号");
+        alert('请输入账号')
       } else {
         searchList({ name: this.listQuery.name }).then((response) => {
-          this.list = response.data;
-          this.total = response.total;
-        });
+          this.list = response.data
+          this.total = response.total
+        })
       }
-    },
-  },
-};
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped>

+ 0 - 5
tests/unit/.eslintrc.js

@@ -1,5 +0,0 @@
-module.exports = {
-  env: {
-    jest: true
-  }
-}

+ 0 - 18
tests/unit/components/Hamburger.spec.js

@@ -1,18 +0,0 @@
-import { shallowMount } from '@vue/test-utils'
-import Hamburger from '@/components/Hamburger/index.vue'
-describe('Hamburger.vue', () => {
-  it('toggle click', () => {
-    const wrapper = shallowMount(Hamburger)
-    const mockFn = jest.fn()
-    wrapper.vm.$on('toggleClick', mockFn)
-    wrapper.find('.hamburger').trigger('click')
-    expect(mockFn).toBeCalled()
-  })
-  it('prop isActive', () => {
-    const wrapper = shallowMount(Hamburger)
-    wrapper.setProps({ isActive: true })
-    expect(wrapper.contains('.is-active')).toBe(true)
-    wrapper.setProps({ isActive: false })
-    expect(wrapper.contains('.is-active')).toBe(false)
-  })
-})

+ 0 - 22
tests/unit/components/SvgIcon.spec.js

@@ -1,22 +0,0 @@
-import { shallowMount } from '@vue/test-utils'
-import SvgIcon from '@/components/SvgIcon/index.vue'
-describe('SvgIcon.vue', () => {
-  it('iconClass', () => {
-    const wrapper = shallowMount(SvgIcon, {
-      propsData: {
-        iconClass: 'test'
-      }
-    })
-    expect(wrapper.find('use').attributes().href).toBe('#icon-test')
-  })
-  it('className', () => {
-    const wrapper = shallowMount(SvgIcon, {
-      propsData: {
-        iconClass: 'test'
-      }
-    })
-    expect(wrapper.classes().length).toBe(1)
-    wrapper.setProps({ className: 'test' })
-    expect(wrapper.classes().includes('test')).toBe(true)
-  })
-})

+ 0 - 29
tests/unit/utils/formatTime.spec.js

@@ -1,29 +0,0 @@
-import { formatTime } from '@/utils/index.js'
-describe('Utils:formatTime', () => {
-  const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
-  const retrofit = 5 * 1000
-
-  it('ten digits timestamp', () => {
-    expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分')
-  })
-  it('test now', () => {
-    expect(formatTime(+new Date() - 1)).toBe('刚刚')
-  })
-  it('less two minute', () => {
-    expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前')
-  })
-  it('less two hour', () => {
-    expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前')
-  })
-  it('less one day', () => {
-    expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前')
-  })
-  it('more than one day', () => {
-    expect(formatTime(d)).toBe('7月13日17时54分')
-  })
-  it('format', () => {
-    expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
-    expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
-    expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
-  })
-})

+ 0 - 14
tests/unit/utils/param2Obj.spec.js

@@ -1,14 +0,0 @@
-import { param2Obj } from '@/utils/index.js'
-describe('Utils:param2Obj', () => {
-  const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95'
-
-  it('param2Obj test', () => {
-    expect(param2Obj(url)).toEqual({
-      name: 'bill',
-      age: '29',
-      sex: '1',
-      field: window.btoa('test'),
-      key: '测试'
-    })
-  })
-})

+ 0 - 37
tests/unit/utils/parseTime.spec.js

@@ -1,37 +0,0 @@
-import { parseTime } from '@/utils/index.js'
-
-describe('Utils:parseTime', () => {
-  const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
-  it('timestamp', () => {
-    expect(parseTime(d)).toBe('2018-07-13 17:54:01')
-  })
-
-  it('timestamp string', () => {
-    expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01')
-  })
-
-  it('ten digits timestamp', () => {
-    expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
-  })
-  it('new Date', () => {
-    expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01')
-  })
-  it('format', () => {
-    expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
-    expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
-    expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
-  })
-  it('get the day of the week', () => {
-    expect(parseTime(d, '{a}')).toBe('五') // 星期五
-  })
-  it('get the day of the week', () => {
-    expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日
-  })
-  it('empty argument', () => {
-    expect(parseTime()).toBeNull()
-  })
-
-  it('null', () => {
-    expect(parseTime(null)).toBeNull()
-  })
-})

+ 0 - 28
tests/unit/utils/validate.spec.js

@@ -1,28 +0,0 @@
-import { validUsername, validURL, validLowerCase, validUpperCase, validAlphabets } from '@/utils/validate.js'
-describe('Utils:validate', () => {
-  it('validUsername', () => {
-    expect(validUsername('admin')).toBe(true)
-    expect(validUsername('editor')).toBe(true)
-    expect(validUsername('xxxx')).toBe(false)
-  })
-  it('validURL', () => {
-    expect(validURL('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(validURL('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(validURL('github.com/PanJiaChen/vue-element-admin')).toBe(false)
-  })
-  it('validLowerCase', () => {
-    expect(validLowerCase('abc')).toBe(true)
-    expect(validLowerCase('Abc')).toBe(false)
-    expect(validLowerCase('123abc')).toBe(false)
-  })
-  it('validUpperCase', () => {
-    expect(validUpperCase('ABC')).toBe(true)
-    expect(validUpperCase('Abc')).toBe(false)
-    expect(validUpperCase('123ABC')).toBe(false)
-  })
-  it('validAlphabets', () => {
-    expect(validAlphabets('ABC')).toBe(true)
-    expect(validAlphabets('Abc')).toBe(true)
-    expect(validAlphabets('123aBC')).toBe(false)
-  })
-})