소스 검색

Merge remote-tracking branch 'origin/master'

tianyunperfect 2 년 전
부모
커밋
d6a40d9f2f
96개의 변경된 파일742개의 추가작업 그리고 4047개의 파일을 삭제
  1. 2 1
      .gitignore
  2. 0 21
      element-demo/LICENSE
  3. 0 102
      element-demo/README-zh.md
  4. 0 90
      element-demo/README.md
  5. 0 14
      element-demo/babel.config.js
  6. 0 35
      element-demo/build/index.js
  7. 0 24
      element-demo/jest.config.js
  8. 0 9
      element-demo/jsconfig.json
  9. 0 59
      element-demo/mock/index.js
  10. 0 81
      element-demo/mock/mock-server.js
  11. 0 29
      element-demo/mock/table.js
  12. 0 71
      element-demo/mock/table1.js
  13. 0 84
      element-demo/mock/user.js
  14. 0 25
      element-demo/mock/utils.js
  15. 0 61
      element-demo/package.json
  16. 0 8
      element-demo/postcss.config.js
  17. BIN
      element-demo/public/favicon.ico
  18. 0 17
      element-demo/public/index.html
  19. 0 11
      element-demo/src/App.vue
  20. 0 9
      element-demo/src/api/table.js
  21. 0 34
      element-demo/src/api/table1.js
  22. 0 24
      element-demo/src/api/user.js
  23. BIN
      element-demo/src/assets/404_images/404.png
  24. BIN
      element-demo/src/assets/404_images/404_cloud.png
  25. 0 78
      element-demo/src/components/Breadcrumb/index.vue
  26. 0 44
      element-demo/src/components/Hamburger/index.vue
  27. 0 62
      element-demo/src/components/SvgIcon/index.vue
  28. 0 9
      element-demo/src/icons/index.js
  29. 0 0
      element-demo/src/icons/svg/dashboard.svg
  30. 0 1
      element-demo/src/icons/svg/example.svg
  31. 0 1
      element-demo/src/icons/svg/eye-open.svg
  32. 0 1
      element-demo/src/icons/svg/eye.svg
  33. 0 0
      element-demo/src/icons/svg/form.svg
  34. 0 1
      element-demo/src/icons/svg/link.svg
  35. 0 1
      element-demo/src/icons/svg/nested.svg
  36. 0 1
      element-demo/src/icons/svg/password.svg
  37. 0 1
      element-demo/src/icons/svg/table.svg
  38. 0 1
      element-demo/src/icons/svg/tree.svg
  39. 0 1
      element-demo/src/icons/svg/user.svg
  40. 0 22
      element-demo/src/icons/svgo.yml
  41. 0 40
      element-demo/src/layout/components/AppMain.vue
  42. 0 138
      element-demo/src/layout/components/Navbar.vue
  43. 0 26
      element-demo/src/layout/components/Sidebar/FixiOSBug.js
  44. 0 41
      element-demo/src/layout/components/Sidebar/Item.vue
  45. 0 43
      element-demo/src/layout/components/Sidebar/Link.vue
  46. 0 82
      element-demo/src/layout/components/Sidebar/Logo.vue
  47. 0 95
      element-demo/src/layout/components/Sidebar/SidebarItem.vue
  48. 0 57
      element-demo/src/layout/components/Sidebar/index.vue
  49. 0 3
      element-demo/src/layout/components/index.js
  50. 0 91
      element-demo/src/layout/index.vue
  51. 0 45
      element-demo/src/layout/mixin/ResizeHandler.js
  52. 0 43
      element-demo/src/main.js
  53. 0 64
      element-demo/src/permission.js
  54. 0 127
      element-demo/src/router/index.js
  55. 0 16
      element-demo/src/settings.js
  56. 0 11
      element-demo/src/store/index.js
  57. 0 30
      element-demo/src/store/modules/app.js
  58. 0 17
      element-demo/src/store/modules/settings.js
  59. 0 67
      element-demo/src/store/modules/user.js
  60. 0 49
      element-demo/src/styles/element-ui.scss
  61. 0 65
      element-demo/src/styles/index.scss
  62. 0 28
      element-demo/src/styles/mixin.scss
  63. 0 226
      element-demo/src/styles/sidebar.scss
  64. 0 48
      element-demo/src/styles/transition.scss
  65. 0 25
      element-demo/src/styles/variables.scss
  66. 0 15
      element-demo/src/utils/auth.js
  67. 0 10
      element-demo/src/utils/get-page-title.js
  68. 0 117
      element-demo/src/utils/index.js
  69. 0 85
      element-demo/src/utils/request.js
  70. 0 20
      element-demo/src/utils/validate.js
  71. 0 228
      element-demo/src/views/404.vue
  72. 0 32
      element-demo/src/views/dashboard/index.vue
  73. 0 85
      element-demo/src/views/form/index.vue
  74. 0 240
      element-demo/src/views/login/index.vue
  75. 0 79
      element-demo/src/views/table/index.vue
  76. 0 219
      element-demo/src/views/table1/index.vue
  77. 0 5
      element-demo/tests/unit/.eslintrc.js
  78. 0 98
      element-demo/tests/unit/components/Breadcrumb.spec.js
  79. 0 18
      element-demo/tests/unit/components/Hamburger.spec.js
  80. 0 22
      element-demo/tests/unit/components/SvgIcon.spec.js
  81. 0 30
      element-demo/tests/unit/utils/formatTime.spec.js
  82. 0 14
      element-demo/tests/unit/utils/param2Obj.spec.js
  83. 0 35
      element-demo/tests/unit/utils/parseTime.spec.js
  84. 0 17
      element-demo/tests/unit/utils/validate.spec.js
  85. 0 0
      element-demo/tmp.js
  86. 0 123
      element-demo/vue.config.js
  87. 0 9
      layui-demo/layui-demo.iml
  88. 0 0
      layui-demo/tmp.js
  89. 0 0
      monkey/monkey.iml
  90. 28 7
      monkey/util.js
  91. 180 0
      simple-demo/bootstrapTest.html
  92. 166 0
      simple-demo/history_list.html
  93. 3 3
      simple-demo/index.html
  94. 75 15
      simple-demo/location.html
  95. 288 0
      simple-demo/location_list.html
  96. 0 11
      tmp/calendar.html

+ 2 - 1
.gitignore

@@ -1,3 +1,4 @@
 node_modules
 package-lock.json
-.idea
+.idea
+dist

+ 0 - 21
element-demo/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 - 102
element-demo/README-zh.md

@@ -1,102 +0,0 @@
-# vue-admin-template
-
-> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
-
-[线上地址](http://panjiachen.github.io/vue-admin-template)
-
-[国内访问](https://panjiachen.gitee.io/vue-admin-template)
-
-目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。
-
-## Extra
-
-如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
-
-## 相关项目
-
-- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
-
-- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
-
-- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
-
-- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
-
-写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
-
-- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
-- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
-- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
-- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
-- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
-
-## Build Setup
-
-```bash
-# 克隆项目
-git clone https://github.com/PanJiaChen/vue-admin-template.git
-
-# 进入项目目录
-cd vue-admin-template
-
-# 安装依赖
-npm install
-
-# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
-npm install --registry=https://registry.npm.taobao.org
-
-# 启动服务
-npm run dev
-```
-
-浏览器访问 [http://localhost:9528](http://localhost:9528)
-
-## 发布
-
-```bash
-# 构建测试环境
-npm run build:stage
-
-# 构建生产环境
-npm run build:prod
-```
-
-## 其它
-
-```bash
-# 预览发布环境效果
-npm run preview
-
-# 预览发布环境效果 + 静态资源分析
-npm run preview -- --report
-
-# 代码格式检查
-npm run lint
-
-# 代码格式检查并自动修复
-npm run lint -- --fix
-```
-
-更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
-
-## 购买贴纸
-
-你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
-
-## Demo
-
-![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
-
-## Browsers support
-
-Modern browsers and Internet Explorer 10+.
-
-| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
-| --------- | --------- | --------- | --------- |
-| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
-
-## License
-
-[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
-
-Copyright (c) 2017-present PanJiaChen

+ 0 - 90
element-demo/README.md

@@ -1,90 +0,0 @@
-# vue-admin-template
-
-English | [简体中文](./README-zh.md)
-
-> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
-
-**Live demo:** http://panjiachen.github.io/vue-admin-template
-
-
-**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
-
-## Build Setup
-
-```bash
-# clone the project
-git clone https://github.com/PanJiaChen/vue-admin-template.git
-
-# enter the project directory
-cd vue-admin-template
-
-# install dependency
-npm install
-
-# develop
-npm run dev
-```
-
-This will automatically open http://localhost:9528
-
-## Build
-
-```bash
-# build for test environment
-npm run build:stage
-
-# build for production environment
-npm run build:prod
-```
-
-## Advanced
-
-```bash
-# preview the release environment effect
-npm run preview
-
-# preview the release environment effect + static resource analysis
-npm run preview -- --report
-
-# code format check
-npm run lint
-
-# code format check and auto fix
-npm run lint -- --fix
-```
-
-Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
-
-## Demo
-
-![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
-
-## Extra
-
-If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
-
-For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
-
-## Related Project
-
-- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
-
-- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
-
-- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
-
-- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
-
-## Browsers support
-
-Modern browsers and Internet Explorer 10+.
-
-| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
-| --------- | --------- | --------- | --------- |
-| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
-
-## License
-
-[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
-
-Copyright (c) 2017-present PanJiaChen

+ 0 - 14
element-demo/babel.config.js

@@ -1,14 +0,0 @@
-module.exports = {
-  presets: [
-    // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
-    '@vue/cli-plugin-babel/preset'
-  ],
-  'env': {
-    'development': {
-      // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
-      // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
-      // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
-      'plugins': ['dynamic-import-node']
-    }
-  }
-}

+ 0 - 35
element-demo/build/index.js

@@ -1,35 +0,0 @@
-const { run } = require('runjs')
-const chalk = require('chalk')
-const config = require('../vue.config.js')
-const rawArgv = process.argv.slice(2)
-const args = rawArgv.join(' ')
-
-if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
-  const report = rawArgv.includes('--report')
-
-  run(`vue-cli-service build ${args}`)
-
-  const port = 9526
-  const publicPath = config.publicPath
-
-  var connect = require('connect')
-  var serveStatic = require('serve-static')
-  const app = connect()
-
-  app.use(
-    publicPath,
-    serveStatic('./dist', {
-      index: ['index.html', '/']
-    })
-  )
-
-  app.listen(port, function () {
-    console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`))
-    if (report) {
-      console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`))
-    }
-
-  })
-} else {
-  run(`vue-cli-service build ${args}`)
-}

+ 0 - 24
element-demo/jest.config.js

@@ -1,24 +0,0 @@
-module.exports = {
-  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
-  transform: {
-    '^.+\\.vue$': 'vue-jest',
-    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
-      'jest-transform-stub',
-    '^.+\\.jsx?$': 'babel-jest'
-  },
-  moduleNameMapper: {
-    '^@/(.*)$': '<rootDir>/src/$1'
-  },
-  snapshotSerializers: ['jest-serializer-vue'],
-  testMatch: [
-    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
-  ],
-  collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
-  coverageDirectory: '<rootDir>/tests/unit/coverage',
-  // 'collectCoverage': true,
-  'coverageReporters': [
-    'lcov',
-    'text-summary'
-  ],
-  testURL: 'http://localhost/'
-}

+ 0 - 9
element-demo/jsconfig.json

@@ -1,9 +0,0 @@
-{
-  "compilerOptions": {
-    "baseUrl": "./",
-    "paths": {
-        "@/*": ["src/*"]
-    }
-  },
-  "exclude": ["node_modules", "dist"]
-}

+ 0 - 59
element-demo/mock/index.js

@@ -1,59 +0,0 @@
-const Mock = require('mockjs')
-const { param2Obj } = require('./utils')
-
-const user = require('./user')
-const table = require('./table')
-const table1 = require('./table1')
-
-const mocks = [
-  ...user,
-  ...table,
-  ...table1
-]
-
-// 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
element-demo/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 - 29
element-demo/mock/table.js

@@ -1,29 +0,0 @@
-const Mock = require('mockjs')
-
-const data = Mock.mock({
-  'items|30': [{
-    id: '@id',
-    title: '@sentence(10, 20)',
-    'status|1': ['published', 'draft', 'deleted'],
-    author: 'name',
-    display_time: '@datetime',
-    pageviews: '@integer(300, 5000)'
-  }]
-})
-
-module.exports = [
-  {
-    url: '/vue-admin-template/table/list',
-    type: 'get',
-    response: config => {
-      const items = data.items
-      return {
-        code: 20000,
-        data: {
-          total: items.length,
-          items: items
-        }
-      }
-    }
-  }
-]

+ 0 - 71
element-demo/mock/table1.js

@@ -1,71 +0,0 @@
-const Mock = require('mockjs')
-
-module.exports = [
-  {
-    url: '/article/list',
-    type: 'get',
-    response: config => {
-      console.log(config.query)
-      console.log(config.body)
-
-      const data = Mock.mock({
-        code: 20000,
-        flag: true,
-        data: {
-          'total|100-200': 1,
-          'list|10': [{
-            'id|+1': 1,
-            name: '@name',
-            email: '@email',
-            date: '@date'
-          }]
-        }
-      })
-
-      return data
-    }
-  },
-
-  {
-    url: '/article/detail',
-    type: 'get',
-    response: config => {
-      const detail = Mock.mock({
-        code: 20000,
-        flag: true,
-        data: {
-          'id|1-19': 1,
-          name: '@name',
-          email: '@email'
-        }
-
-      })
-      return detail
-    }
-  },
-
-  {
-    url: '/article/save',
-    type: 'post',
-    response: x => {
-      console.log(x.body)
-      return {
-        code: 20000,
-        flag: true,
-        data: 'success'
-      }
-    }
-  },
-
-  {
-    url: '/article/deleteOne',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        flag: true,
-        data: 'success'
-      }
-    }
-  }
-]

+ 0 - 84
element-demo/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-admin-template/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-admin-template/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-admin-template/user/logout',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        data: 'success'
-      }
-    }
-  }
-]

+ 0 - 25
element-demo/mock/utils.js

@@ -1,25 +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
-}
-
-module.exports = {
-  param2Obj
-}

+ 0 - 61
element-demo/package.json

@@ -1,61 +0,0 @@
-{
-  "name": "vue-admin-template",
-  "version": "4.4.0",
-  "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
-  "author": "Pan <panfree23@gmail.com>",
-  "scripts": {
-    "dev": "vue-cli-service serve",
-    "build:prod": "vue-cli-service build",
-    "build:stage": "vue-cli-service build --mode staging",
-    "preview": "node build/index.js --preview",
-    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
-    "lint": "eslint --ext .js,.vue src",
-    "test:unit": "jest --clearCache && vue-cli-service test:unit",
-    "test:ci": "npm run lint && npm run test:unit"
-  },
-  "dependencies": {
-    "axios": "^0.24.0",
-    "core-js": "3.6.5",
-    "element-ui": "2.13.2",
-    "js-cookie": "2.2.0",
-    "normalize.css": "7.0.0",
-    "nprogress": "0.2.0",
-    "path-to-regexp": "2.4.0",
-    "vue": "2.6.10",
-    "vue-router": "3.0.6"
-  },
-  "devDependencies": {
-    "@vue/cli-plugin-babel": "4.4.4",
-    "@vue/cli-plugin-eslint": "4.4.4",
-    "@vue/cli-plugin-unit-jest": "4.4.4",
-    "@vue/cli-service": "4.4.4",
-    "@vue/test-utils": "1.0.0-beta.29",
-    "autoprefixer": "9.5.1",
-    "babel-eslint": "10.1.0",
-    "babel-jest": "23.6.0",
-    "babel-plugin-dynamic-import-node": "2.3.3",
-    "chalk": "2.4.2",
-    "connect": "3.6.6",
-    "eslint": "6.7.2",
-    "eslint-plugin-vue": "6.2.2",
-    "html-webpack-plugin": "3.2.0",
-    "mockjs": "1.0.1-beta3",
-    "runjs": "4.3.2",
-    "sass": "1.26.8",
-    "sass-loader": "8.0.2",
-    "script-ext-html-webpack-plugin": "2.1.3",
-    "serve-static": "1.13.2",
-    "svg-sprite-loader": "4.1.3",
-    "svgo": "1.2.2",
-    "vue-template-compiler": "2.6.10"
-  },
-  "browserslist": [
-    "> 1%",
-    "last 2 versions"
-  ],
-  "engines": {
-    "node": ">=8.9",
-    "npm": ">= 3.0.0"
-  },
-  "license": "MIT"
-}

+ 0 - 8
element-demo/postcss.config.js

@@ -1,8 +0,0 @@
-// https://github.com/michael-ciniawsky/postcss-load-config
-
-module.exports = {
-  'plugins': {
-    // to edit target browsers: use "browserslist" field in package.json
-    'autoprefixer': {}
-  }
-}

BIN
element-demo/public/favicon.ico


+ 0 - 17
element-demo/public/index.html

@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <title><%= webpackConfig.name %></title>
-  </head>
-  <body>
-    <noscript>
-      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
-    </noscript>
-    <div id="app"></div>
-    <!-- built files will be auto injected -->
-  </body>
-</html>

+ 0 - 11
element-demo/src/App.vue

@@ -1,11 +0,0 @@
-<template>
-  <div id="app">
-    <router-view />
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'App'
-}
-</script>

+ 0 - 9
element-demo/src/api/table.js

@@ -1,9 +0,0 @@
-import request from '@/utils/request'
-
-export function getList(params) {
-  return request({
-    url: '/vue-admin-template/table/list',
-    method: 'get',
-    params
-  })
-}

+ 0 - 34
element-demo/src/api/table1.js

@@ -1,34 +0,0 @@
-import request from '@/utils/request'
-
-export function fetchList(query) {
-  return request({
-    url: '/article/list',
-    method: 'get',
-    params: query
-  })
-}
-
-export function fetchOne(id) {
-  return request({
-    url: '/article/detail',
-    method: 'get',
-    params: { id }
-  })
-}
-
-// create Or update
-export function saveOne(data) {
-  return request({
-    url: '/article/save',
-    method: 'post',
-    data
-  })
-}
-
-export function deleteOne(id) {
-  return request({
-    url: '/article/delete',
-    method: 'post',
-    params: { id }
-  })
-}

+ 0 - 24
element-demo/src/api/user.js

@@ -1,24 +0,0 @@
-import request from '@/utils/request'
-
-export function login(data) {
-  return request({
-    url: '/vue-admin-template/user/login',
-    method: 'post',
-    data
-  })
-}
-
-export function getInfo(token) {
-  return request({
-    url: '/vue-admin-template/user/info',
-    method: 'get',
-    params: { token }
-  })
-}
-
-export function logout() {
-  return request({
-    url: '/vue-admin-template/user/logout',
-    method: 'post'
-  })
-}

BIN
element-demo/src/assets/404_images/404.png


BIN
element-demo/src/assets/404_images/404_cloud.png


+ 0 - 78
element-demo/src/components/Breadcrumb/index.vue

@@ -1,78 +0,0 @@
-<template>
-  <el-breadcrumb class="app-breadcrumb" separator="/">
-    <transition-group name="breadcrumb">
-      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
-        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
-      </el-breadcrumb-item>
-    </transition-group>
-  </el-breadcrumb>
-</template>
-
-<script>
-import pathToRegexp from 'path-to-regexp'
-
-export default {
-  data() {
-    return {
-      levelList: null
-    }
-  },
-  watch: {
-    $route() {
-      this.getBreadcrumb()
-    }
-  },
-  created() {
-    this.getBreadcrumb()
-  },
-  methods: {
-    getBreadcrumb() {
-      // only show routes with meta.title
-      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
-      const first = matched[0]
-
-      if (!this.isDashboard(first)) {
-        matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
-      }
-
-      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
-    },
-    isDashboard(route) {
-      const name = route && route.name
-      if (!name) {
-        return false
-      }
-      return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
-    },
-    pathCompile(path) {
-      // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
-      const { params } = this.$route
-      var toPath = pathToRegexp.compile(path)
-      return toPath(params)
-    },
-    handleLink(item) {
-      const { redirect, path } = item
-      if (redirect) {
-        this.$router.push(redirect)
-        return
-      }
-      this.$router.push(this.pathCompile(path))
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.app-breadcrumb.el-breadcrumb {
-  display: inline-block;
-  font-size: 14px;
-  line-height: 50px;
-  margin-left: 8px;
-
-  .no-redirect {
-    color: #97a8be;
-    cursor: text;
-  }
-}
-</style>

+ 0 - 44
element-demo/src/components/Hamburger/index.vue

@@ -1,44 +0,0 @@
-<template>
-  <div style="padding: 0 15px;" @click="toggleClick">
-    <svg
-      :class="{'is-active':isActive}"
-      class="hamburger"
-      viewBox="0 0 1024 1024"
-      xmlns="http://www.w3.org/2000/svg"
-      width="64"
-      height="64"
-    >
-      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
-    </svg>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'Hamburger',
-  props: {
-    isActive: {
-      type: Boolean,
-      default: false
-    }
-  },
-  methods: {
-    toggleClick() {
-      this.$emit('toggleClick')
-    }
-  }
-}
-</script>
-
-<style scoped>
-.hamburger {
-  display: inline-block;
-  vertical-align: middle;
-  width: 20px;
-  height: 20px;
-}
-
-.hamburger.is-active {
-  transform: rotate(180deg);
-}
-</style>

+ 0 - 62
element-demo/src/components/SvgIcon/index.vue

@@ -1,62 +0,0 @@
-<template>
-  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
-  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
-    <use :xlink:href="iconName" />
-  </svg>
-</template>
-
-<script>
-// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
-import { isExternal } from '@/utils/validate'
-
-export default {
-  name: 'SvgIcon',
-  props: {
-    iconClass: {
-      type: String,
-      required: true
-    },
-    className: {
-      type: String,
-      default: ''
-    }
-  },
-  computed: {
-    isExternal() {
-      return isExternal(this.iconClass)
-    },
-    iconName() {
-      return `#icon-${this.iconClass}`
-    },
-    svgClass() {
-      if (this.className) {
-        return 'svg-icon ' + this.className
-      } else {
-        return 'svg-icon'
-      }
-    },
-    styleExternalIcon() {
-      return {
-        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
-        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
-      }
-    }
-  }
-}
-</script>
-
-<style scoped>
-.svg-icon {
-  width: 1em;
-  height: 1em;
-  vertical-align: -0.15em;
-  fill: currentColor;
-  overflow: hidden;
-}
-
-.svg-external-icon {
-  background-color: currentColor;
-  mask-size: cover!important;
-  display: inline-block;
-}
-</style>

+ 0 - 9
element-demo/src/icons/index.js

@@ -1,9 +0,0 @@
-import Vue from 'vue'
-import SvgIcon from '@/components/SvgIcon'// svg component
-
-// register globally
-Vue.component('svg-icon', SvgIcon)
-
-const req = require.context('./svg', false, /\.svg$/)
-const requireAll = requireContext => requireContext.keys().map(requireContext)
-requireAll(req)

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
element-demo/src/icons/svg/dashboard.svg


+ 0 - 1
element-demo/src/icons/svg/example.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/eye-open.svg

@@ -1 +0,0 @@
-<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/eye.svg

@@ -1 +0,0 @@
-<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
element-demo/src/icons/svg/form.svg


+ 0 - 1
element-demo/src/icons/svg/link.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/nested.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/password.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/table.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/tree.svg

@@ -1 +0,0 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

+ 0 - 1
element-demo/src/icons/svg/user.svg

@@ -1 +0,0 @@
-<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

+ 0 - 22
element-demo/src/icons/svgo.yml

@@ -1,22 +0,0 @@
-# replace default config
-
-# multipass: true
-# full: true
-
-plugins:
-
-  # - name
-  #
-  # or:
-  # - name: false
-  # - name: true
-  #
-  # or:
-  # - name:
-  #     param1: 1
-  #     param2: 2
-
-- removeAttrs:
-    attrs:
-      - 'fill'
-      - 'fill-rule'

+ 0 - 40
element-demo/src/layout/components/AppMain.vue

@@ -1,40 +0,0 @@
-<template>
-  <section class="app-main">
-    <transition name="fade-transform" mode="out-in">
-      <router-view :key="key" />
-    </transition>
-  </section>
-</template>
-
-<script>
-export default {
-  name: 'AppMain',
-  computed: {
-    key() {
-      return this.$route.path
-    }
-  }
-}
-</script>
-
-<style scoped>
-.app-main {
-  /*50 = navbar  */
-  min-height: calc(100vh - 50px);
-  width: 100%;
-  position: relative;
-  overflow: hidden;
-}
-.fixed-header+.app-main {
-  padding-top: 50px;
-}
-</style>
-
-<style lang="scss">
-// fix css style bug in open el-dialog
-.el-popup-parent--hidden {
-  .fixed-header {
-    padding-right: 15px;
-  }
-}
-</style>

+ 0 - 138
element-demo/src/layout/components/Navbar.vue

@@ -1,138 +0,0 @@
-<template>
-  <div class="navbar">
-    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
-
-    <breadcrumb class="breadcrumb-container" />
-
-    <div class="right-menu">
-      <el-dropdown class="avatar-container" trigger="click">
-        <div class="avatar-wrapper">
-          <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
-          <i class="el-icon-caret-bottom" />
-        </div>
-        <el-dropdown-menu slot="dropdown" class="user-dropdown">
-          <router-link to="/">
-            <el-dropdown-item>
-              Home
-            </el-dropdown-item>
-          </router-link>
-          <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
-            <el-dropdown-item>Github</el-dropdown-item>
-          </a>
-          <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
-            <el-dropdown-item>Docs</el-dropdown-item>
-          </a>
-          <el-dropdown-item divided @click.native="logout">
-            <span style="display:block;">Log Out</span>
-          </el-dropdown-item>
-        </el-dropdown-menu>
-      </el-dropdown>
-    </div>
-  </div>
-</template>
-
-<script>
-import Breadcrumb from '@/components/Breadcrumb'
-import Hamburger from '@/components/Hamburger'
-
-export default {
-  components: {
-    Breadcrumb,
-    Hamburger
-  },
-  data() {
-    return {
-      'sidebar': this.store.app.state.sidebar,
-      'avatar': this.store.user.state.avatar
-    }
-  },
-  methods: {
-    toggleSideBar() {
-      this.store.app.toggleSideBar()
-    },
-    async logout() {
-      await this.store.user.logout()
-      this.$router.push(`/login?redirect=${this.$route.fullPath}`)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.navbar {
-  height: 50px;
-  overflow: hidden;
-  position: relative;
-  background: #fff;
-  box-shadow: 0 1px 4px rgba(0,21,41,.08);
-
-  .hamburger-container {
-    line-height: 46px;
-    height: 100%;
-    float: left;
-    cursor: pointer;
-    transition: background .3s;
-    -webkit-tap-highlight-color:transparent;
-
-    &:hover {
-      background: rgba(0, 0, 0, .025)
-    }
-  }
-
-  .breadcrumb-container {
-    float: left;
-  }
-
-  .right-menu {
-    float: right;
-    height: 100%;
-    line-height: 50px;
-
-    &:focus {
-      outline: none;
-    }
-
-    .right-menu-item {
-      display: inline-block;
-      padding: 0 8px;
-      height: 100%;
-      font-size: 18px;
-      color: #5a5e66;
-      vertical-align: text-bottom;
-
-      &.hover-effect {
-        cursor: pointer;
-        transition: background .3s;
-
-        &:hover {
-          background: rgba(0, 0, 0, .025)
-        }
-      }
-    }
-
-    .avatar-container {
-      margin-right: 30px;
-
-      .avatar-wrapper {
-        margin-top: 5px;
-        position: relative;
-
-        .user-avatar {
-          cursor: pointer;
-          width: 40px;
-          height: 40px;
-          border-radius: 10px;
-        }
-
-        .el-icon-caret-bottom {
-          cursor: pointer;
-          position: absolute;
-          right: -20px;
-          top: 25px;
-          font-size: 12px;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 26
element-demo/src/layout/components/Sidebar/FixiOSBug.js

@@ -1,26 +0,0 @@
-export default {
-  computed: {
-    device() {
-      return this.store.app.state.device
-    }
-  },
-  mounted() {
-    // In order to fix the click on menu on the ios device will trigger the mouseleave bug
-    // https://github.com/PanJiaChen/vue-element-admin/issues/1135
-    this.fixBugIniOS()
-  },
-  methods: {
-    fixBugIniOS() {
-      const $subMenu = this.$refs.subMenu
-      if ($subMenu) {
-        const handleMouseleave = $subMenu.handleMouseleave
-        $subMenu.handleMouseleave = (e) => {
-          if (this.device === 'mobile') {
-            return
-          }
-          handleMouseleave(e)
-        }
-      }
-    }
-  }
-}

+ 0 - 41
element-demo/src/layout/components/Sidebar/Item.vue

@@ -1,41 +0,0 @@
-<script>
-export default {
-  name: 'MenuItem',
-  functional: true,
-  props: {
-    icon: {
-      type: String,
-      default: ''
-    },
-    title: {
-      type: String,
-      default: ''
-    }
-  },
-  render(h, context) {
-    const { icon, title } = context.props
-    const vnodes = []
-
-    if (icon) {
-      if (icon.includes('el-icon')) {
-        vnodes.push(<i class={[icon, 'sub-el-icon']} />)
-      } else {
-        vnodes.push(<svg-icon icon-class={icon}/>)
-      }
-    }
-
-    if (title) {
-      vnodes.push(<span slot='title'>{(title)}</span>)
-    }
-    return vnodes
-  }
-}
-</script>
-
-<style scoped>
-.sub-el-icon {
-  color: currentColor;
-  width: 1em;
-  height: 1em;
-}
-</style>

+ 0 - 43
element-demo/src/layout/components/Sidebar/Link.vue

@@ -1,43 +0,0 @@
-<template>
-  <component :is="type" v-bind="linkProps(to)">
-    <slot />
-  </component>
-</template>
-
-<script>
-import { isExternal } from '@/utils/validate'
-
-export default {
-  props: {
-    to: {
-      type: String,
-      required: true
-    }
-  },
-  computed: {
-    isExternal() {
-      return isExternal(this.to)
-    },
-    type() {
-      if (this.isExternal) {
-        return 'a'
-      }
-      return 'router-link'
-    }
-  },
-  methods: {
-    linkProps(to) {
-      if (this.isExternal) {
-        return {
-          href: to,
-          target: '_blank',
-          rel: 'noopener'
-        }
-      }
-      return {
-        to: to
-      }
-    }
-  }
-}
-</script>

+ 0 - 82
element-demo/src/layout/components/Sidebar/Logo.vue

@@ -1,82 +0,0 @@
-<template>
-  <div class="sidebar-logo-container" :class="{'collapse':collapse}">
-    <transition name="sidebarLogoFade">
-      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
-        <h1 v-else class="sidebar-title">{{ title }} </h1>
-      </router-link>
-      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
-        <h1 class="sidebar-title">{{ title }} </h1>
-      </router-link>
-    </transition>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'SidebarLogo',
-  props: {
-    collapse: {
-      type: Boolean,
-      required: true
-    }
-  },
-  data() {
-    return {
-      title: 'Vue Admin Template',
-      logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.sidebarLogoFade-enter-active {
-  transition: opacity 1.5s;
-}
-
-.sidebarLogoFade-enter,
-.sidebarLogoFade-leave-to {
-  opacity: 0;
-}
-
-.sidebar-logo-container {
-  position: relative;
-  width: 100%;
-  height: 50px;
-  line-height: 50px;
-  background: #2b2f3a;
-  text-align: center;
-  overflow: hidden;
-
-  & .sidebar-logo-link {
-    height: 100%;
-    width: 100%;
-
-    & .sidebar-logo {
-      width: 32px;
-      height: 32px;
-      vertical-align: middle;
-      margin-right: 12px;
-    }
-
-    & .sidebar-title {
-      display: inline-block;
-      margin: 0;
-      color: #fff;
-      font-weight: 600;
-      line-height: 50px;
-      font-size: 14px;
-      font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
-      vertical-align: middle;
-    }
-  }
-
-  &.collapse {
-    .sidebar-logo {
-      margin-right: 0px;
-    }
-  }
-}
-</style>

+ 0 - 95
element-demo/src/layout/components/Sidebar/SidebarItem.vue

@@ -1,95 +0,0 @@
-<template>
-  <div v-if="!item.hidden">
-    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
-      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
-        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
-          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
-        </el-menu-item>
-      </app-link>
-    </template>
-
-    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
-      <template slot="title">
-        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
-      </template>
-      <sidebar-item
-        v-for="child in item.children"
-        :key="child.path"
-        :is-nest="true"
-        :item="child"
-        :base-path="resolvePath(child.path)"
-        class="nest-menu"
-      />
-    </el-submenu>
-  </div>
-</template>
-
-<script>
-import path from 'path'
-import { isExternal } from '@/utils/validate'
-import Item from './Item'
-import AppLink from './Link'
-import FixiOSBug from './FixiOSBug'
-
-export default {
-  name: 'SidebarItem',
-  components: { Item, AppLink },
-  mixins: [FixiOSBug],
-  props: {
-    // route object
-    item: {
-      type: Object,
-      required: true
-    },
-    isNest: {
-      type: Boolean,
-      default: false
-    },
-    basePath: {
-      type: String,
-      default: ''
-    }
-  },
-  data() {
-    // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
-    // TODO: refactor with render function
-    this.onlyOneChild = null
-    return {}
-  },
-  methods: {
-    hasOneShowingChild(children = [], parent) {
-      const showingChildren = children.filter(item => {
-        if (item.hidden) {
-          return false
-        } else {
-          // Temp set(will be used if only has one showing child)
-          this.onlyOneChild = item
-          return true
-        }
-      })
-
-      // When there is only one child router, the child router is displayed by default
-      if (showingChildren.length === 1) {
-        return true
-      }
-
-      // Show parent if there are no child router to display
-      if (showingChildren.length === 0) {
-        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
-        return true
-      }
-
-      return false
-    },
-    resolvePath(routePath) {
-      if (isExternal(routePath)) {
-        return routePath
-      }
-      if (isExternal(this.basePath)) {
-        return this.basePath
-      }
-      return path.resolve(this.basePath, routePath)
-    }
-  }
-}
-</script>

+ 0 - 57
element-demo/src/layout/components/Sidebar/index.vue

@@ -1,57 +0,0 @@
-<template>
-  <div :class="{'has-logo':showLogo}">
-    <logo v-if="showLogo" :collapse="isCollapse" />
-    <el-scrollbar wrap-class="scrollbar-wrapper">
-      <el-menu
-        :default-active="activeMenu"
-        :collapse="isCollapse"
-        :background-color="variables.menuBg"
-        :text-color="variables.menuText"
-        :unique-opened="false"
-        :active-text-color="variables.menuActiveText"
-        :collapse-transition="false"
-        mode="vertical"
-      >
-        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
-      </el-menu>
-    </el-scrollbar>
-  </div>
-</template>
-
-<script>
-import Logo from './Logo'
-import SidebarItem from './SidebarItem'
-import variables from '@/styles/variables.scss'
-
-export default {
-  components: { SidebarItem, Logo },
-  data() {
-    return {
-      'sidebar': this.store.app.state.sidebar
-    }
-  },
-  computed: {
-    routes() {
-      return this.$router.options.routes
-    },
-    activeMenu() {
-      const route = this.$route
-      const { meta, path } = route
-      // if set path, the sidebar will highlight the path you set
-      if (meta.activeMenu) {
-        return meta.activeMenu
-      }
-      return path
-    },
-    showLogo() {
-      return this.store.settings.state.sidebarLogo
-    },
-    variables() {
-      return variables
-    },
-    isCollapse() {
-      return !this.sidebar.opened
-    }
-  }
-}
-</script>

+ 0 - 3
element-demo/src/layout/components/index.js

@@ -1,3 +0,0 @@
-export { default as Navbar } from './Navbar'
-export { default as Sidebar } from './Sidebar'
-export { default as AppMain } from './AppMain'

+ 0 - 91
element-demo/src/layout/index.vue

@@ -1,91 +0,0 @@
-<template>
-  <div :class="classObj" class="app-wrapper">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
-    <sidebar class="sidebar-container" />
-    <div class="main-container">
-      <div :class="{'fixed-header':fixedHeader}">
-        <navbar />
-      </div>
-      <app-main />
-    </div>
-  </div>
-</template>
-
-<script>
-import { Navbar, Sidebar, AppMain } from './components'
-import ResizeMixin from './mixin/ResizeHandler'
-
-export default {
-  name: 'Layout',
-  components: {
-    Navbar,
-    Sidebar,
-    AppMain
-  },
-  mixins: [ResizeMixin],
-  data() {
-    return {
-      sidebar: this.store.app.state.sidebar,
-      device: this.store.app.state.device,
-      fixedHeader: this.store.settings.state.fixedHeader
-    }
-  },
-  computed: {
-    classObj() {
-      return {
-        hideSidebar: !this.sidebar.opened,
-        openSidebar: this.sidebar.opened,
-        withoutAnimation: this.sidebar.withoutAnimation,
-        mobile: this.device === 'mobile'
-      }
-    }
-  },
-  methods: {
-    handleClickOutside() {
-      this.store.app.closeSideBar({ withoutAnimation: false })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
-
-  .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 {
-    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 - 45
element-demo/src/layout/mixin/ResizeHandler.js

@@ -1,45 +0,0 @@
-import store from '@/store'
-
-const { body } = document
-const WIDTH = 992 // refer to Bootstrap's responsive design
-
-export default {
-  watch: {
-    $route(route) {
-      if (this.device === 'mobile' && this.sidebar.opened) {
-        store.app.closeSideBar({ withoutAnimation: false })
-      }
-    }
-  },
-  beforeMount() {
-    window.addEventListener('resize', this.$_resizeHandler)
-  },
-  beforeDestroy() {
-    window.removeEventListener('resize', this.$_resizeHandler)
-  },
-  mounted() {
-    const isMobile = this.$_isMobile()
-    if (isMobile) {
-      store.app.toggleDevice('mobile')
-      store.app.closeSideBar({ withoutAnimation: true })
-    }
-  },
-  methods: {
-    // use $_ for mixins properties
-    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
-    $_isMobile() {
-      const rect = body.getBoundingClientRect()
-      return rect.width - 1 < WIDTH
-    },
-    $_resizeHandler() {
-      if (!document.hidden) {
-        const isMobile = this.$_isMobile()
-        store.app.toggleSideBar(isMobile ? 'mobile' : 'desktop')
-
-        if (isMobile) {
-          store.app.closeSideBar({ withoutAnimation: true })
-        }
-      }
-    }
-  }
-}

+ 0 - 43
element-demo/src/main.js

@@ -1,43 +0,0 @@
-import Vue from 'vue'
-
-import 'normalize.css/normalize.css' // A modern alternative to CSS resets
-
-import ElementUI from 'element-ui'
-import 'element-ui/lib/theme-chalk/index.css'
-import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n
-
-import '@/styles/index.scss' // global css
-
-import App from './App'
-import store from './store'
-import router from './router'
-
-import '@/icons' // icon
-import '@/permission' // permission control
-
-/**
- * If you don't want to use mock-server
- * you want to use MockJs for mock api
- * you can execute: mockXHR()
- *
- * Currently MockJs will be used in the production environment,
- * please remove it before going online ! ! !
- */
-if (process.env.NODE_ENV === 'production') {
-  const { mockXHR } = require('../mock')
-  mockXHR()
-}
-
-// set ElementUI lang to EN
-Vue.use(ElementUI, { locale })
-// 如果想要中文版 element-ui,按如下方式声明
-// Vue.use(ElementUI)
-
-Vue.config.productionTip = false
-Vue.prototype.store = store
-
-new Vue({
-  el: '#app',
-  router,
-  render: h => h(App)
-})

+ 0 - 64
element-demo/src/permission.js

@@ -1,64 +0,0 @@
-import router from './router'
-import store from './store'
-import { Message } from 'element-ui'
-import NProgress from 'nprogress' // progress bar
-import 'nprogress/nprogress.css' // progress bar style
-import { getToken } from '@/utils/auth' // get token from cookie
-import getPageTitle from '@/utils/get-page-title'
-
-NProgress.configure({ showSpinner: false }) // NProgress Configuration
-
-const whiteList = ['/login'] // no redirect whitelist
-
-router.beforeEach(async(to, from, next) => {
-  // start progress bar
-  NProgress.start()
-
-  // set page title
-  document.title = getPageTitle(to.meta.title)
-
-  // determine whether the user has logged in
-  const hasToken = getToken()
-
-  if (hasToken) {
-    if (to.path === '/login') {
-      // if is logged in, redirect to the home page
-      next({ path: '/' })
-      NProgress.done()
-    } else {
-      const hasGetUserInfo = store.user.state.name
-      if (hasGetUserInfo) {
-        next()
-      } else {
-        try {
-          // get user info
-          await store.user.getInfo()
-
-          next()
-        } catch (error) {
-          // remove token and go to login page to re-login
-          await store.user.resetToken()
-          Message.error(error || 'Has Error')
-          next(`/login?redirect=${to.path}`)
-          NProgress.done()
-        }
-      }
-    }
-  } else {
-    /* has no token*/
-
-    if (whiteList.indexOf(to.path) !== -1) {
-      // in the free login whitelist, go directly
-      next()
-    } else {
-      // other pages that do not have permission to access are redirected to the login page.
-      next(`/login?redirect=${to.path}`)
-      NProgress.done()
-    }
-  }
-})
-
-router.afterEach(() => {
-  // finish progress bar
-  NProgress.done()
-})

+ 0 - 127
element-demo/src/router/index.js

@@ -1,127 +0,0 @@
-import Vue from 'vue'
-import Router from 'vue-router'
-
-Vue.use(Router)
-
-/* Layout */
-import Layout from '@/layout'
-
-/**
- * Note: sub-menu only appear when route children.length >= 1
- * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
- *
- * hidden: true                   if set true, item will not show in the sidebar(default is false)
- * alwaysShow: true               if set true, will always show the root menu
- *                                if not set alwaysShow, when item has more than one children route,
- *                                it will becomes nested mode, otherwise not show the root menu
- * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
- * name:'router-name'             the name is used by <keep-alive> (must set!!!)
- * meta : {
-    roles: ['admin','editor']    control the page roles (you can set multiple roles)
-    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
-    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
-    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
-    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
-  }
- */
-
-/**
- * constantRoutes
- * a base page that does not have permission requirements
- * all roles can be accessed
- */
-export const constantRoutes = [
-  {
-    path: '/login',
-    component: () => import('@/views/login/index'),
-    hidden: true
-  },
-
-  {
-    path: '/404',
-    component: () => import('@/views/404'),
-    hidden: true
-  },
-
-  {
-    path: '/',
-    component: Layout,
-    redirect: '/dashboard',
-    children: [{
-      path: 'dashboard',
-      name: 'Dashboard',
-      component: () => import('@/views/dashboard/index'),
-      meta: { title: 'Dashboard', icon: 'dashboard' }
-    }]
-  },
-
-  {
-    path: '/example',
-    component: Layout,
-    redirect: '/example/table',
-    name: 'Example',
-    meta: { title: 'Example', icon: 'el-icon-s-help' },
-    children: [
-      {
-        path: 'table',
-        name: 'Table',
-        component: () => import('@/views/table/index'),
-        meta: { title: 'Table', icon: 'table' }
-      }
-    ]
-  },
-  {
-    path: '/table1',
-    component: Layout,
-    children: [
-      {
-        path: 'index',
-        name: 'Table1',
-        component: () => import('@/views/table1/index'),
-        meta: { title: 'Table1', icon: 'table' }
-      }
-    ]
-  },
-  {
-    path: '/form',
-    component: Layout,
-    children: [
-      {
-        path: 'index',
-        name: 'Form',
-        component: () => import('@/views/form/index'),
-        meta: { title: 'Form', icon: 'form' }
-      }
-    ]
-  },
-
-  {
-    path: 'external-link',
-    component: Layout,
-    children: [
-      {
-        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-        meta: { title: 'External Link', icon: 'link' }
-      }
-    ]
-  },
-
-  // 404 page must be placed at the end !!!
-  { path: '*', redirect: '/404', hidden: true }
-]
-
-const createRouter = () => new Router({
-  // mode: 'history', // require service support
-  scrollBehavior: () => ({ y: 0 }),
-  routes: constantRoutes
-})
-
-const router = createRouter()
-
-// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
-export function resetRouter() {
-  const newRouter = createRouter()
-  router.matcher = newRouter.matcher // reset router
-}
-
-export default router

+ 0 - 16
element-demo/src/settings.js

@@ -1,16 +0,0 @@
-module.exports = {
-
-  title: '标题',
-
-  /**
-   * @type {boolean} true | false
-   * @description Whether fix the header
-   */
-  fixedHeader: false,
-
-  /**
-   * @type {boolean} true | false
-   * @description Whether show the logo in sidebar
-   */
-  sidebarLogo: true
-}

+ 0 - 11
element-demo/src/store/index.js

@@ -1,11 +0,0 @@
-import app from './modules/app'
-import settings from './modules/settings'
-import user from './modules/user'
-
-const store = {
-  app,
-  user,
-  settings
-}
-
-export default store

+ 0 - 30
element-demo/src/store/modules/app.js

@@ -1,30 +0,0 @@
-import Cookies from 'js-cookie'
-
-export default {
-  state: {
-    sidebar: {
-      opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
-      withoutAnimation: false
-    },
-    device: 'desktop'
-  },
-
-  toggleSideBar: function() {
-    this.state.sidebar.opened = !this.state.sidebar.opened
-    this.state.sidebar.withoutAnimation = false
-    if (this.state.sidebar.opened) {
-      Cookies.set('sidebarStatus', 1)
-    } else {
-      Cookies.set('sidebarStatus', 0)
-    }
-  },
-  closeSideBar: function({ withoutAnimation }) {
-    Cookies.set('sidebarStatus', 0)
-    this.state.sidebar.opened = false
-    this.state.sidebar.withoutAnimation = withoutAnimation
-  },
-
-  toggleDevice: function(device) {
-    this.state.device = device
-  }
-}

+ 0 - 17
element-demo/src/store/modules/settings.js

@@ -1,17 +0,0 @@
-import defaultSettings from '@/settings'
-
-const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
-
-export default {
-  state: {
-    showSettings: showSettings,
-    fixedHeader: fixedHeader,
-    sidebarLogo: sidebarLogo
-  },
-  changeSetting: function({ key, value }) {
-    // eslint-disable-next-line no-prototype-builtins
-    if (this.state.hasOwnProperty(key)) {
-      this.state[key] = value
-    }
-  }
-}

+ 0 - 67
element-demo/src/store/modules/user.js

@@ -1,67 +0,0 @@
-import { login, logout, getInfo } from '@/api/user'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import { resetRouter } from '@/router'
-
-function getDefaultState() {
-  return {
-    token: getToken(),
-    name: '',
-    avatar: ''
-  }
-}
-
-export default {
-  state: getDefaultState(),
-  login: function(userInfo) {
-    const { username, password } = userInfo
-    return new Promise((resolve, reject) => {
-      login({ username: username.trim(), password: password }).then(response => {
-        const { data } = response
-        this.state.token = data.token
-        setToken(data.token)
-        resolve()
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  getInfo() {
-    return new Promise((resolve, reject) => {
-      getInfo(this.state.token).then(response => {
-        const { data } = response
-
-        if (!data) {
-          return reject('Verification failed, please Login again.')
-        }
-
-        const { name, avatar } = data
-        this.state.name = name
-        this.state.avatar = avatar
-        resolve(data)
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  logout() {
-    return new Promise((resolve, reject) => {
-      logout(this.state.token).then(() => {
-        removeToken() // must remove  token  first
-        resetRouter()
-        Object.assign(this.state, getDefaultState())
-        resolve()
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  // remove token
-  resetToken() {
-    return new Promise(resolve => {
-      removeToken() // must remove  token  first
-      Object.assign(this.state, getDefaultState())
-      resolve()
-    })
-  }
-}
-

+ 0 - 49
element-demo/src/styles/element-ui.scss

@@ -1,49 +0,0 @@
-// cover some element-ui styles
-
-.el-breadcrumb__inner,
-.el-breadcrumb__inner a {
-  font-weight: 400 !important;
-}
-
-.el-upload {
-  input[type="file"] {
-    display: none !important;
-  }
-}
-
-.el-upload__input {
-  display: none;
-}
-
-
-// to fixed https://github.com/ElemeFE/element/issues/2461
-.el-dialog {
-  transform: none;
-  left: 0;
-  position: relative;
-  margin: 0 auto;
-}
-
-// refine element ui upload
-.upload-container {
-  .el-upload {
-    width: 100%;
-
-    .el-upload-dragger {
-      width: 100%;
-      height: 200px;
-    }
-  }
-}
-
-// dropdown
-.el-dropdown-menu {
-  a {
-    display: block
-  }
-}
-
-// to fix el-date-picker css style
-.el-range-separator {
-  box-sizing: content-box;
-}

+ 0 - 65
element-demo/src/styles/index.scss

@@ -1,65 +0,0 @@
-@import './variables.scss';
-@import './mixin.scss';
-@import './transition.scss';
-@import './element-ui.scss';
-@import './sidebar.scss';
-
-body {
-  height: 100%;
-  -moz-osx-font-smoothing: grayscale;
-  -webkit-font-smoothing: antialiased;
-  text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
-}
-
-label {
-  font-weight: 700;
-}
-
-html {
-  height: 100%;
-  box-sizing: border-box;
-}
-
-#app {
-  height: 100%;
-}
-
-*,
-*:before,
-*:after {
-  box-sizing: inherit;
-}
-
-a:focus,
-a:active {
-  outline: none;
-}
-
-a,
-a:focus,
-a:hover {
-  cursor: pointer;
-  color: inherit;
-  text-decoration: none;
-}
-
-div:focus {
-  outline: none;
-}
-
-.clearfix {
-  &:after {
-    visibility: hidden;
-    display: block;
-    font-size: 0;
-    content: " ";
-    clear: both;
-    height: 0;
-  }
-}
-
-// main-container global css
-.app-container {
-  padding: 20px;
-}

+ 0 - 28
element-demo/src/styles/mixin.scss

@@ -1,28 +0,0 @@
-@mixin clearfix {
-  &:after {
-    content: "";
-    display: table;
-    clear: both;
-  }
-}
-
-@mixin scrollBar {
-  &::-webkit-scrollbar-track-piece {
-    background: #d3dce6;
-  }
-
-  &::-webkit-scrollbar {
-    width: 6px;
-  }
-
-  &::-webkit-scrollbar-thumb {
-    background: #99a9bf;
-    border-radius: 20px;
-  }
-}
-
-@mixin relative {
-  position: relative;
-  width: 100%;
-  height: 100%;
-}

+ 0 - 226
element-demo/src/styles/sidebar.scss

@@ -1,226 +0,0 @@
-#app {
-
-  .main-container {
-    min-height: 100%;
-    transition: margin-left .28s;
-    margin-left: $sideBarWidth;
-    position: relative;
-  }
-
-  .sidebar-container {
-    transition: width 0.28s;
-    width: $sideBarWidth !important;
-    background-color: $menuBg;
-    height: 100%;
-    position: fixed;
-    font-size: 0px;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    z-index: 1001;
-    overflow: hidden;
-
-    // reset element-ui css
-    .horizontal-collapse-transition {
-      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
-    }
-
-    .scrollbar-wrapper {
-      overflow-x: hidden !important;
-    }
-
-    .el-scrollbar__bar.is-vertical {
-      right: 0px;
-    }
-
-    .el-scrollbar {
-      height: 100%;
-    }
-
-    &.has-logo {
-      .el-scrollbar {
-        height: calc(100% - 50px);
-      }
-    }
-
-    .is-horizontal {
-      display: none;
-    }
-
-    a {
-      display: inline-block;
-      width: 100%;
-      overflow: hidden;
-    }
-
-    .svg-icon {
-      margin-right: 16px;
-    }
-
-    .sub-el-icon {
-      margin-right: 12px;
-      margin-left: -2px;
-    }
-
-    .el-menu {
-      border: none;
-      height: 100%;
-      width: 100% !important;
-    }
-
-    // menu hover
-    .submenu-title-noDropdown,
-    .el-submenu__title {
-      &:hover {
-        background-color: $menuHover !important;
-      }
-    }
-
-    .is-active>.el-submenu__title {
-      color: $subMenuActiveText !important;
-    }
-
-    & .nest-menu .el-submenu>.el-submenu__title,
-    & .el-submenu .el-menu-item {
-      min-width: $sideBarWidth !important;
-      background-color: $subMenuBg !important;
-
-      &:hover {
-        background-color: $subMenuHover !important;
-      }
-    }
-  }
-
-  .hideSidebar {
-    .sidebar-container {
-      width: 54px !important;
-    }
-
-    .main-container {
-      margin-left: 54px;
-    }
-
-    .submenu-title-noDropdown {
-      padding: 0 !important;
-      position: relative;
-
-      .el-tooltip {
-        padding: 0 !important;
-
-        .svg-icon {
-          margin-left: 20px;
-        }
-
-        .sub-el-icon {
-          margin-left: 19px;
-        }
-      }
-    }
-
-    .el-submenu {
-      overflow: hidden;
-
-      &>.el-submenu__title {
-        padding: 0 !important;
-
-        .svg-icon {
-          margin-left: 20px;
-        }
-
-        .sub-el-icon {
-          margin-left: 19px;
-        }
-
-        .el-submenu__icon-arrow {
-          display: none;
-        }
-      }
-    }
-
-    .el-menu--collapse {
-      .el-submenu {
-        &>.el-submenu__title {
-          &>span {
-            height: 0;
-            width: 0;
-            overflow: hidden;
-            visibility: hidden;
-            display: inline-block;
-          }
-        }
-      }
-    }
-  }
-
-  .el-menu--collapse .el-menu .el-submenu {
-    min-width: $sideBarWidth !important;
-  }
-
-  // mobile responsive
-  .mobile {
-    .main-container {
-      margin-left: 0px;
-    }
-
-    .sidebar-container {
-      transition: transform .28s;
-      width: $sideBarWidth !important;
-    }
-
-    &.hideSidebar {
-      .sidebar-container {
-        pointer-events: none;
-        transition-duration: 0.3s;
-        transform: translate3d(-$sideBarWidth, 0, 0);
-      }
-    }
-  }
-
-  .withoutAnimation {
-
-    .main-container,
-    .sidebar-container {
-      transition: none;
-    }
-  }
-}
-
-// when menu collapsed
-.el-menu--vertical {
-  &>.el-menu {
-    .svg-icon {
-      margin-right: 16px;
-    }
-    .sub-el-icon {
-      margin-right: 12px;
-      margin-left: -2px;
-    }
-  }
-
-  .nest-menu .el-submenu>.el-submenu__title,
-  .el-menu-item {
-    &:hover {
-      // you can use $subMenuHover
-      background-color: $menuHover !important;
-    }
-  }
-
-  // the scroll bar appears when the subMenu is too long
-  >.el-menu--popup {
-    max-height: 100vh;
-    overflow-y: auto;
-
-    &::-webkit-scrollbar-track-piece {
-      background: #d3dce6;
-    }
-
-    &::-webkit-scrollbar {
-      width: 6px;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      background: #99a9bf;
-      border-radius: 20px;
-    }
-  }
-}

+ 0 - 48
element-demo/src/styles/transition.scss

@@ -1,48 +0,0 @@
-// global transition css
-
-/* fade */
-.fade-enter-active,
-.fade-leave-active {
-  transition: opacity 0.28s;
-}
-
-.fade-enter,
-.fade-leave-active {
-  opacity: 0;
-}
-
-/* fade-transform */
-.fade-transform-leave-active,
-.fade-transform-enter-active {
-  transition: all .5s;
-}
-
-.fade-transform-enter {
-  opacity: 0;
-  transform: translateX(-30px);
-}
-
-.fade-transform-leave-to {
-  opacity: 0;
-  transform: translateX(30px);
-}
-
-/* breadcrumb transition */
-.breadcrumb-enter-active,
-.breadcrumb-leave-active {
-  transition: all .5s;
-}
-
-.breadcrumb-enter,
-.breadcrumb-leave-active {
-  opacity: 0;
-  transform: translateX(20px);
-}
-
-.breadcrumb-move {
-  transition: all .5s;
-}
-
-.breadcrumb-leave-active {
-  position: absolute;
-}

+ 0 - 25
element-demo/src/styles/variables.scss

@@ -1,25 +0,0 @@
-// sidebar
-$menuText:#bfcbd9;
-$menuActiveText:#409EFF;
-$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
-
-$menuBg:#304156;
-$menuHover:#263445;
-
-$subMenuBg:#1f2d3d;
-$subMenuHover:#001528;
-
-$sideBarWidth: 210px;
-
-// the :export directive is the magic sauce for webpack
-// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
-:export {
-  menuText: $menuText;
-  menuActiveText: $menuActiveText;
-  subMenuActiveText: $subMenuActiveText;
-  menuBg: $menuBg;
-  menuHover: $menuHover;
-  subMenuBg: $subMenuBg;
-  subMenuHover: $subMenuHover;
-  sideBarWidth: $sideBarWidth;
-}

+ 0 - 15
element-demo/src/utils/auth.js

@@ -1,15 +0,0 @@
-import Cookies from 'js-cookie'
-
-const TokenKey = 'vue_admin_template_token'
-
-export function getToken() {
-  return Cookies.get(TokenKey)
-}
-
-export function setToken(token) {
-  return Cookies.set(TokenKey, token)
-}
-
-export function removeToken() {
-  return Cookies.remove(TokenKey)
-}

+ 0 - 10
element-demo/src/utils/get-page-title.js

@@ -1,10 +0,0 @@
-import defaultSettings from '@/settings'
-
-const title = defaultSettings.title || 'Vue Admin Template'
-
-export default function getPageTitle(pageTitle) {
-  if (pageTitle) {
-    return `${pageTitle} - ${title}`
-  }
-  return `${title}`
-}

+ 0 - 117
element-demo/src/utils/index.js

@@ -1,117 +0,0 @@
-/**
- * Created by PanJiaChen on 16/11/18.
- */
-
-/**
- * Parse the time to string
- * @param {(Object|string|number)} time
- * @param {string} cFormat
- * @returns {string | null}
- */
-export function parseTime(time, cFormat) {
-  if (arguments.length === 0 || !time) {
-    return null
-  }
-  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
-  let date
-  if (typeof time === 'object') {
-    date = time
-  } else {
-    if ((typeof time === 'string')) {
-      if ((/^[0-9]+$/.test(time))) {
-        // support "1548221490638"
-        time = parseInt(time)
-      } else {
-        // support safari
-        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
-        time = time.replace(new RegExp(/-/gm), '/')
-      }
-    }
-
-    if ((typeof time === 'number') && (time.toString().length === 10)) {
-      time = time * 1000
-    }
-    date = new Date(time)
-  }
-  const formatObj = {
-    y: date.getFullYear(),
-    m: date.getMonth() + 1,
-    d: date.getDate(),
-    h: date.getHours(),
-    i: date.getMinutes(),
-    s: date.getSeconds(),
-    a: date.getDay()
-  }
-  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
-    const value = formatObj[key]
-    // Note: getDay() returns 0 on Sunday
-    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
-    return value.toString().padStart(2, '0')
-  })
-  return time_str
-}
-
-/**
- * @param {number} time
- * @param {string} option
- * @returns {string}
- */
-export function formatTime(time, option) {
-  if (('' + time).length === 10) {
-    time = parseInt(time) * 1000
-  } else {
-    time = +time
-  }
-  const d = new Date(time)
-  const now = Date.now()
-
-  const diff = (now - d) / 1000
-
-  if (diff < 30) {
-    return '刚刚'
-  } else if (diff < 3600) {
-    // less 1 hour
-    return Math.ceil(diff / 60) + '分钟前'
-  } else if (diff < 3600 * 24) {
-    return Math.ceil(diff / 3600) + '小时前'
-  } else if (diff < 3600 * 24 * 2) {
-    return '1天前'
-  }
-  if (option) {
-    return parseTime(time, option)
-  } else {
-    return (
-      d.getMonth() +
-      1 +
-      '月' +
-      d.getDate() +
-      '日' +
-      d.getHours() +
-      '时' +
-      d.getMinutes() +
-      '分'
-    )
-  }
-}
-
-/**
- * @param {string} url
- * @returns {Object}
- */
-export 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
-}

+ 0 - 85
element-demo/src/utils/request.js

@@ -1,85 +0,0 @@
-import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
-import store from '@/store'
-import { getToken } from '@/utils/auth'
-
-// create an axios instance
-const service = axios.create({
-  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
-  // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 5000 // request timeout
-})
-
-// request interceptor
-service.interceptors.request.use(
-  config => {
-    // do something before request is sent
-
-    if (store.user.state.token) {
-      // let each request carry token
-      // ['X-Token'] is a custom headers key
-      // please modify it according to the actual situation
-      config.headers['X-Token'] = getToken()
-    }
-    return config
-  },
-  error => {
-    // do something with request error
-    console.log(error) // for debug
-    return Promise.reject(error)
-  }
-)
-
-// response interceptor
-service.interceptors.response.use(
-  /**
-   * If you want to get http information such as headers or status
-   * Please return  response => response
-  */
-
-  /**
-   * Determine the request status by custom code
-   * Here is just an example
-   * You can also judge the status by HTTP Status Code
-   */
-  response => {
-    const res = response.data
-
-    // if the custom code is not 20000, it is judged as an error.
-    if (res.code !== 20000) {
-      Message({
-        message: res.message || 'Error',
-        type: 'error',
-        duration: 5 * 1000
-      })
-
-      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
-        // to re-login
-        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
-          confirmButtonText: 'Re-Login',
-          cancelButtonText: 'Cancel',
-          type: 'warning'
-        }).then(() => {
-          store.user.resetToken().then(() => {
-            location.reload()
-          })
-        })
-      }
-      return Promise.reject(new Error(res.message || 'Error'))
-    } else {
-      return res
-    }
-  },
-  error => {
-    console.log('err' + error) // for debug
-    Message({
-      message: error.message,
-      type: 'error',
-      duration: 5 * 1000
-    })
-    return Promise.reject(error)
-  }
-)
-
-export default service

+ 0 - 20
element-demo/src/utils/validate.js

@@ -1,20 +0,0 @@
-/**
- * Created by PanJiaChen on 16/11/18.
- */
-
-/**
- * @param {string} path
- * @returns {Boolean}
- */
-export function isExternal(path) {
-  return /^(https?:|mailto:|tel:)/.test(path)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function validUsername(str) {
-  const valid_map = ['admin', 'editor']
-  return valid_map.indexOf(str.trim()) >= 0
-}

+ 0 - 228
element-demo/src/views/404.vue

@@ -1,228 +0,0 @@
-<template>
-  <div class="wscn-http404-container">
-    <div class="wscn-http404">
-      <div class="pic-404">
-        <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
-        <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
-        <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
-        <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
-      </div>
-      <div class="bullshit">
-        <div class="bullshit__oops">OOPS!</div>
-        <div class="bullshit__info">All rights reserved
-          <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
-        </div>
-        <div class="bullshit__headline">{{ message }}</div>
-        <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
-        <a href="" class="bullshit__return-home">Back to home</a>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-
-export default {
-  name: 'Page404',
-  computed: {
-    message() {
-      return 'The webmaster said that you can not enter this page...'
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.wscn-http404-container{
-  transform: translate(-50%,-50%);
-  position: absolute;
-  top: 40%;
-  left: 50%;
-}
-.wscn-http404 {
-  position: relative;
-  width: 1200px;
-  padding: 0 50px;
-  overflow: hidden;
-  .pic-404 {
-    position: relative;
-    float: left;
-    width: 600px;
-    overflow: hidden;
-    &__parent {
-      width: 100%;
-    }
-    &__child {
-      position: absolute;
-      &.left {
-        width: 80px;
-        top: 17px;
-        left: 220px;
-        opacity: 0;
-        animation-name: cloudLeft;
-        animation-duration: 2s;
-        animation-timing-function: linear;
-        animation-fill-mode: forwards;
-        animation-delay: 1s;
-      }
-      &.mid {
-        width: 46px;
-        top: 10px;
-        left: 420px;
-        opacity: 0;
-        animation-name: cloudMid;
-        animation-duration: 2s;
-        animation-timing-function: linear;
-        animation-fill-mode: forwards;
-        animation-delay: 1.2s;
-      }
-      &.right {
-        width: 62px;
-        top: 100px;
-        left: 500px;
-        opacity: 0;
-        animation-name: cloudRight;
-        animation-duration: 2s;
-        animation-timing-function: linear;
-        animation-fill-mode: forwards;
-        animation-delay: 1s;
-      }
-      @keyframes cloudLeft {
-        0% {
-          top: 17px;
-          left: 220px;
-          opacity: 0;
-        }
-        20% {
-          top: 33px;
-          left: 188px;
-          opacity: 1;
-        }
-        80% {
-          top: 81px;
-          left: 92px;
-          opacity: 1;
-        }
-        100% {
-          top: 97px;
-          left: 60px;
-          opacity: 0;
-        }
-      }
-      @keyframes cloudMid {
-        0% {
-          top: 10px;
-          left: 420px;
-          opacity: 0;
-        }
-        20% {
-          top: 40px;
-          left: 360px;
-          opacity: 1;
-        }
-        70% {
-          top: 130px;
-          left: 180px;
-          opacity: 1;
-        }
-        100% {
-          top: 160px;
-          left: 120px;
-          opacity: 0;
-        }
-      }
-      @keyframes cloudRight {
-        0% {
-          top: 100px;
-          left: 500px;
-          opacity: 0;
-        }
-        20% {
-          top: 120px;
-          left: 460px;
-          opacity: 1;
-        }
-        80% {
-          top: 180px;
-          left: 340px;
-          opacity: 1;
-        }
-        100% {
-          top: 200px;
-          left: 300px;
-          opacity: 0;
-        }
-      }
-    }
-  }
-  .bullshit {
-    position: relative;
-    float: left;
-    width: 300px;
-    padding: 30px 0;
-    overflow: hidden;
-    &__oops {
-      font-size: 32px;
-      font-weight: bold;
-      line-height: 40px;
-      color: #1482f0;
-      opacity: 0;
-      margin-bottom: 20px;
-      animation-name: slideUp;
-      animation-duration: 0.5s;
-      animation-fill-mode: forwards;
-    }
-    &__headline {
-      font-size: 20px;
-      line-height: 24px;
-      color: #222;
-      font-weight: bold;
-      opacity: 0;
-      margin-bottom: 10px;
-      animation-name: slideUp;
-      animation-duration: 0.5s;
-      animation-delay: 0.1s;
-      animation-fill-mode: forwards;
-    }
-    &__info {
-      font-size: 13px;
-      line-height: 21px;
-      color: grey;
-      opacity: 0;
-      margin-bottom: 30px;
-      animation-name: slideUp;
-      animation-duration: 0.5s;
-      animation-delay: 0.2s;
-      animation-fill-mode: forwards;
-    }
-    &__return-home {
-      display: block;
-      float: left;
-      width: 110px;
-      height: 36px;
-      background: #1482f0;
-      border-radius: 100px;
-      text-align: center;
-      color: #ffffff;
-      opacity: 0;
-      font-size: 14px;
-      line-height: 36px;
-      cursor: pointer;
-      animation-name: slideUp;
-      animation-duration: 0.5s;
-      animation-delay: 0.3s;
-      animation-fill-mode: forwards;
-    }
-    @keyframes slideUp {
-      0% {
-        transform: translateY(60px);
-        opacity: 0;
-      }
-      100% {
-        transform: translateY(0);
-        opacity: 1;
-      }
-    }
-  }
-}
-</style>

+ 0 - 32
element-demo/src/views/dashboard/index.vue

@@ -1,32 +0,0 @@
-<template>
-  <div class="dashboard-container">
-    <div class="dashboard-text">name: {{ name }}</div>
-  </div>
-</template>
-
-<script>
-
-export default {
-  name: 'Dashboard',
-  data() {
-    return {
-      'name': this.store.user.state.name
-    }
-  },
-  mounted() {
-    console.log(this.store)
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.dashboard {
-  &-container {
-    margin: 30px;
-  }
-  &-text {
-    font-size: 30px;
-    line-height: 46px;
-  }
-}
-</style>

+ 0 - 85
element-demo/src/views/form/index.vue

@@ -1,85 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form ref="form" :model="form" label-width="120px">
-      <el-form-item label="Activity name">
-        <el-input v-model="form.name" />
-      </el-form-item>
-      <el-form-item label="Activity zone">
-        <el-select v-model="form.region" placeholder="please select your zone">
-          <el-option label="Zone one" value="shanghai" />
-          <el-option label="Zone two" value="beijing" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="Activity time">
-        <el-col :span="11">
-          <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
-        </el-col>
-        <el-col :span="2" class="line">-</el-col>
-        <el-col :span="11">
-          <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
-        </el-col>
-      </el-form-item>
-      <el-form-item label="Instant delivery">
-        <el-switch v-model="form.delivery" />
-      </el-form-item>
-      <el-form-item label="Activity type">
-        <el-checkbox-group v-model="form.type">
-          <el-checkbox label="Online activities" name="type" />
-          <el-checkbox label="Promotion activities" name="type" />
-          <el-checkbox label="Offline activities" name="type" />
-          <el-checkbox label="Simple brand exposure" name="type" />
-        </el-checkbox-group>
-      </el-form-item>
-      <el-form-item label="Resources">
-        <el-radio-group v-model="form.resource">
-          <el-radio label="Sponsor" />
-          <el-radio label="Venue" />
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item label="Activity form">
-        <el-input v-model="form.desc" type="textarea" />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="onSubmit">Create</el-button>
-        <el-button @click="onCancel">Cancel</el-button>
-      </el-form-item>
-    </el-form>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      form: {
-        name: '',
-        region: '',
-        date1: '',
-        date2: '',
-        delivery: false,
-        type: [],
-        resource: '',
-        desc: ''
-      }
-    }
-  },
-  methods: {
-    onSubmit() {
-      this.$message('submit!')
-    },
-    onCancel() {
-      this.$message({
-        message: 'cancel!',
-        type: 'warning'
-      })
-    }
-  }
-}
-</script>
-
-<style scoped>
-.line{
-  text-align: center;
-}
-</style>
-

+ 0 - 240
element-demo/src/views/login/index.vue

@@ -1,240 +0,0 @@
-<template>
-  <div class="login-container">
-    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
-             label-position="left">
-
-      <div class="title-container">
-        <h3 class="title">Login Form</h3>
-      </div>
-
-      <el-form-item prop="username">
-        <span class="svg-container">
-          <svg-icon icon-class="user"/>
-        </span>
-        <el-input
-            ref="username"
-            v-model="loginForm.username"
-            placeholder="Username"
-            name="username"
-            type="text"
-            tabindex="1"
-            auto-complete="on"
-        />
-      </el-form-item>
-
-      <el-form-item prop="password">
-        <span class="svg-container">
-          <svg-icon icon-class="password"/>
-        </span>
-        <el-input
-            :key="passwordType"
-            ref="password"
-            v-model="loginForm.password"
-            :type="passwordType"
-            placeholder="Password"
-            name="password"
-            tabindex="2"
-            auto-complete="on"
-            @keyup.enter.native="handleLogin"
-        />
-        <span class="show-pwd" @click="showPwd">
-          <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"/>
-        </span>
-      </el-form-item>
-
-      <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;"
-                 @click.native.prevent="handleLogin">Login
-      </el-button>
-
-      <div class="tips">
-        <span style="margin-right:20px;">username: admin</span>
-        <span> password: any</span>
-      </div>
-
-    </el-form>
-  </div>
-</template>
-
-<script>
-import {validUsername} from '@/utils/validate'
-
-export default {
-  name: 'Login',
-  data() {
-    const validateUsername = (rule, value, callback) => {
-      if (!validUsername(value)) {
-        callback(new Error('Please enter the correct user name'))
-      } else {
-        callback()
-      }
-    }
-    const validatePassword = (rule, value, callback) => {
-      if (value.length < 6) {
-        callback(new Error('The password can not be less than 6 digits'))
-      } else {
-        callback()
-      }
-    }
-    return {
-      loginForm: {
-        username: 'admin',
-        password: '111111'
-      },
-      loginRules: {
-        username: [{required: true, trigger: 'blur', validator: validateUsername}],
-        password: [{required: true, trigger: 'blur', validator: validatePassword}]
-      },
-      loading: false,
-      passwordType: 'password',
-      redirect: undefined
-    }
-  },
-  watch: {
-    $route: {
-      handler: function (route) {
-        this.redirect = route.query && route.query.redirect
-      },
-      immediate: true
-    }
-  },
-  methods: {
-    showPwd() {
-      if (this.passwordType === 'password') {
-        this.passwordType = ''
-      } else {
-        this.passwordType = 'password'
-      }
-      this.$nextTick(() => {
-        this.$refs.password.focus()
-      })
-    },
-    handleLogin() {
-      this.$refs.loginForm.validate(valid => {
-        if (valid) {
-          this.loading = true
-          this.store.user.login(this.loginForm).then(() => {
-            this.$router.push({path: this.redirect || '/'})
-            this.loading = false
-          }).catch(() => {
-            this.loading = false
-          })
-        } else {
-          console.log('error submit!!')
-          return false
-        }
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss">
-/* 修复input 背景不协调 和光标变色 */
-/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
-
-$bg: #283443;
-$light_gray: #fff;
-$cursor: #fff;
-
-@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
-  .login-container .el-input input {
-    color: $cursor;
-  }
-}
-
-/* reset element-ui css */
-.login-container {
-  .el-input {
-    display: inline-block;
-    height: 47px;
-    width: 85%;
-
-    input {
-      background: transparent;
-      border: 0px;
-      -webkit-appearance: none;
-      border-radius: 0px;
-      padding: 12px 5px 12px 15px;
-      color: $light_gray;
-      height: 47px;
-      caret-color: $cursor;
-
-      &:-webkit-autofill {
-        box-shadow: 0 0 0px 1000px $bg inset !important;
-        -webkit-text-fill-color: $cursor !important;
-      }
-    }
-  }
-
-  .el-form-item {
-    border: 1px solid rgba(255, 255, 255, 0.1);
-    background: rgba(0, 0, 0, 0.1);
-    border-radius: 5px;
-    color: #454545;
-  }
-}
-</style>
-
-<style lang="scss" scoped>
-$bg: #2d3a4b;
-$dark_gray: #889aa4;
-$light_gray: #eee;
-
-.login-container {
-  min-height: 100%;
-  width: 100%;
-  background-color: $bg;
-  overflow: hidden;
-
-  .login-form {
-    position: relative;
-    width: 520px;
-    max-width: 100%;
-    padding: 160px 35px 0;
-    margin: 0 auto;
-    overflow: hidden;
-  }
-
-  .tips {
-    font-size: 14px;
-    color: #fff;
-    margin-bottom: 10px;
-
-    span {
-      &:first-of-type {
-        margin-right: 16px;
-      }
-    }
-  }
-
-  .svg-container {
-    padding: 6px 5px 6px 15px;
-    color: $dark_gray;
-    vertical-align: middle;
-    width: 30px;
-    display: inline-block;
-  }
-
-  .title-container {
-    position: relative;
-
-    .title {
-      font-size: 26px;
-      color: $light_gray;
-      margin: 0px auto 40px auto;
-      text-align: center;
-      font-weight: bold;
-    }
-  }
-
-  .show-pwd {
-    position: absolute;
-    right: 10px;
-    top: 7px;
-    font-size: 16px;
-    color: $dark_gray;
-    cursor: pointer;
-    user-select: none;
-  }
-}
-</style>

+ 0 - 79
element-demo/src/views/table/index.vue

@@ -1,79 +0,0 @@
-<template>
-  <div class="app-container">
-    <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">
-          <span>{{ scope.row.author }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Pageviews" width="110" align="center">
-        <template slot-scope="scope">
-          {{ scope.row.pageviews }}
-        </template>
-      </el-table-column>
-      <el-table-column class-name="status-col" label="Status" width="110" align="center">
-        <template slot-scope="scope">
-          <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column align="center" prop="created_at" label="Display_time" width="200">
-        <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 { getList } from '@/api/table'
-
-export default {
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'gray',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  data() {
-    return {
-      list: null,
-      listLoading: true
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      this.listLoading = true
-      getList().then(response => {
-        this.list = response.data.items
-        this.listLoading = false
-      })
-    }
-  }
-}
-</script>

+ 0 - 219
element-demo/src/views/table1/index.vue

@@ -1,219 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form :inline="true" :model="param" class="demo-form-inline">
-      <el-form-item label="名字">
-        <el-input v-model="param.name" placeholder="名字" />
-      </el-form-item>
-      <el-form-item label="日期">
-        <el-input v-model="param.date" />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="queryList">查询</el-button>
-      </el-form-item>
-    </el-form>
-    <template>
-      <!--添加-->
-      <el-row>
-        <el-button @click="createOne()">添加</el-button>
-      </el-row>
-      <!--数据-->
-      <el-table
-        :data="tableData"
-        border
-        style="width: 100%"
-      >
-        <el-table-column
-          fixed
-          prop="date"
-          label="日期"
-          width="150"
-        />
-        <el-table-column
-          prop="name"
-          label="姓名"
-          width="150"
-        />
-        <el-table-column
-          prop="email"
-          label="email地址"
-          width="300"
-        />
-        <el-table-column
-          fixed="right"
-          label="操作"
-          width="100"
-        >
-          <template slot-scope="scope">
-            <el-button
-              type="text"
-              size="small"
-              @click="editOne(scope.row)"
-            >编辑
-            </el-button>
-            <el-button
-              size="small"
-              type="text"
-              @click="deleteAlert(scope.row.id)"
-            >删除
-            </el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <!--编辑层-->
-      <el-dialog title="编辑" :visible.sync="dialogFormVisible">
-        <el-form :model="editNews">
-          <el-form-item label="姓名" :label-width="formLabelWidth">
-            <el-input v-model="editNews.name" autocomplete="off" />
-          </el-form-item>
-          <el-form-item label="Email" :label-width="formLabelWidth">
-            <el-input v-model="editNews.email" placeholder="" />
-          </el-form-item>
-        </el-form>
-        <div slot="footer" class="dialog-footer">
-          <el-button @click="dialogFormVisible = false">取 消</el-button>
-          <el-button type="primary" @click="saveOne">确 定</el-button>
-        </div>
-      </el-dialog>
-
-      <!--删除提示-->
-      <el-dialog
-        title="提示"
-        :visible.sync="dialogVisible"
-        width="30%"
-        :before-close="handleClose"
-      >
-        <span>真的要删吗?</span>
-        <div slot="footer" class="dialog-footer">
-          <el-button @click="dialogVisible = false">取 消</el-button>
-          <el-button type="primary" @click="deleteOne">确 定</el-button>
-        </div>
-      </el-dialog>
-
-      <!--分页-->
-      <div class="block">
-        <el-pagination
-          :current-page="param.page"
-          :page-sizes="[10, 20, 30, 40]"
-          :page-size="param.size"
-          layout="total, sizes, prev, pager, next, jumper"
-          :total="total"
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
-        />
-      </div>
-    </template>
-  </div>
-</template>
-
-<script>
-import { deleteOne, fetchList, fetchOne, saveOne } from '@/api/table1'
-export default {
-  name: 'Table1',
-  data() {
-    return {
-      tableData: [],
-      // 删除层隐藏
-      dialogVisible: false,
-      // 弹出层隐藏
-      dialogFormVisible: false,
-      // 弹出层内容
-      editNews: {
-        name: '',
-        email: ''
-      },
-      // 弹出层大小
-      formLabelWidth: '120px',
-      // 删除使用的id
-      id: '',
-      // 查询参数
-      param: {
-        name: '',
-        date: '',
-        page: 1,
-        size: 10
-      },
-      // 查询返回总条数
-      total: 0
-    }
-  },
-  mounted() {
-    this.queryList()
-  },
-  methods: {
-    // 修改页面展示数据大小
-    handleSizeChange(val) {
-      this.param.size = val
-      this.queryList()
-    },
-    // 修改页码
-    handleCurrentChange(val) {
-      this.param.page = val
-      this.queryList()
-    },
-    // 点击编辑,从后台获取数据
-    editOne(row) {
-      console.log(row)
-      fetchOne(row.id).then(res => {
-        if (res.flag) {
-          this.editNews = res.data
-        }
-      })
-      this.dialogFormVisible = true
-    },
-    // 获取删除行的id
-    deleteAlert(id) {
-      this.id = id
-      this.dialogVisible = true
-    },
-    // 删除
-    deleteOne() {
-      deleteOne(this.id).then(res => {
-        if (res.flag) {
-          this.dialogFormVisible = false
-          this.queryList()
-        } else {
-          alert('删除失败')
-        }
-      })
-      this.dialogVisible = false
-    },
-    // 关闭提示框时,提示是否要关闭
-    handleClose(done) {
-      this.$confirm('确认关闭?')
-        .then(() => {
-          done()
-        })
-        .catch(() => {
-        })
-    },
-    // 点击添加按钮清空
-    createOne() {
-      this.editNews = {}
-      this.dialogFormVisible = true
-    },
-    // 点击确定后发送请求
-    saveOne() {
-      saveOne(this.editNews).then(res => {
-        if (res.flag) {
-          this.dialogFormVisible = false
-          this.queryList()
-        } else {
-          this.$message('添加失败')
-        }
-      })
-    },
-    // 获取数据
-    queryList() {
-      fetchList(this.param).then(res => {
-        if (res.flag) {
-          this.tableData = res.data.list
-          this.total = res.data.total
-        } else {
-          this.tableData = {}
-        }
-      })
-    }
-  }
-}
-</script>

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

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

+ 0 - 98
element-demo/tests/unit/components/Breadcrumb.spec.js

@@ -1,98 +0,0 @@
-import { mount, createLocalVue } from '@vue/test-utils'
-import VueRouter from 'vue-router'
-import ElementUI from 'element-ui'
-import Breadcrumb from '@/components/Breadcrumb/index.vue'
-
-const localVue = createLocalVue()
-localVue.use(VueRouter)
-localVue.use(ElementUI)
-
-const routes = [
-  {
-    path: '/',
-    name: 'home',
-    children: [{
-      path: 'dashboard',
-      name: 'dashboard'
-    }]
-  },
-  {
-    path: '/menu',
-    name: 'menu',
-    children: [{
-      path: 'menu1',
-      name: 'menu1',
-      meta: { title: 'menu1' },
-      children: [{
-        path: 'menu1-1',
-        name: 'menu1-1',
-        meta: { title: 'menu1-1' }
-      },
-      {
-        path: 'menu1-2',
-        name: 'menu1-2',
-        redirect: 'noredirect',
-        meta: { title: 'menu1-2' },
-        children: [{
-          path: 'menu1-2-1',
-          name: 'menu1-2-1',
-          meta: { title: 'menu1-2-1' }
-        },
-        {
-          path: 'menu1-2-2',
-          name: 'menu1-2-2'
-        }]
-      }]
-    }]
-  }]
-
-const router = new VueRouter({
-  routes
-})
-
-describe('Breadcrumb.vue', () => {
-  const wrapper = mount(Breadcrumb, {
-    localVue,
-    router
-  })
-  it('dashboard', () => {
-    router.push('/dashboard')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(1)
-  })
-  it('normal route', () => {
-    router.push('/menu/menu1')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(2)
-  })
-  it('nested route', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-1')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(4)
-  })
-  it('no meta.title', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-2')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(3)
-  })
-  // it('click link', () => {
-  //   router.push('/menu/menu1/menu1-2/menu1-2-2')
-  //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-  //   const second = breadcrumbArray.at(1)
-  //   console.log(breadcrumbArray)
-  //   const href = second.find('a').attributes().href
-  //   expect(href).toBe('#/menu/menu1')
-  // })
-  // it('noRedirect', () => {
-  //   router.push('/menu/menu1/menu1-2/menu1-2-1')
-  //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-  //   const redirectBreadcrumb = breadcrumbArray.at(2)
-  //   expect(redirectBreadcrumb.contains('a')).toBe(false)
-  // })
-  it('last breadcrumb', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-1')
-    const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-    const redirectBreadcrumb = breadcrumbArray.at(3)
-    expect(redirectBreadcrumb.contains('a')).toBe(false)
-  })
-})

+ 0 - 18
element-demo/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
element-demo/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 - 30
element-demo/tests/unit/utils/formatTime.spec.js

@@ -1,30 +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
element-demo/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 - 35
element-demo/tests/unit/utils/parseTime.spec.js

@@ -1,35 +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 - 17
element-demo/tests/unit/utils/validate.spec.js

@@ -1,17 +0,0 @@
-import { validUsername, isExternal } 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('isExternal', () => {
-    expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false)
-    expect(isExternal('/dashboard')).toBe(false)
-    expect(isExternal('./dashboard')).toBe(false)
-    expect(isExternal('dashboard')).toBe(false)
-  })
-})

+ 0 - 0
element-demo/tmp.js


+ 0 - 123
element-demo/vue.config.js

@@ -1,123 +0,0 @@
-'use strict'
-const path = require('path')
-const defaultSettings = require('./src/settings.js')
-
-function resolve(dir) {
-  return path.join(__dirname, dir)
-}
-
-const name = defaultSettings.title || 'vue Admin Template' // page title
-
-// If your port is set to 80,
-// use administrator privileges to execute the command line.
-// For example, Mac: sudo npm run
-// You can change the port by the following methods:
-// port = 9528 npm run dev OR npm run dev --port = 9528
-const port = process.env.port || process.env.npm_config_port || 9528 // dev port
-
-// All configuration item explanations can be find in https://cli.vuejs.org/config/
-module.exports = {
-  /**
-   * You will need to set publicPath if you plan to deploy your site under a sub path,
-   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
-   * then publicPath should be set to "/bar/".
-   * In most cases please use '/' !!!
-   * Detail: https://cli.vuejs.org/config/#publicpath
-   */
-  publicPath: '/',
-  outputDir: 'dist',
-  assetsDir: 'static',
-  lintOnSave: process.env.NODE_ENV === 'development',
-  productionSourceMap: false,
-  devServer: {
-    port: port,
-    open: true,
-    overlay: {
-      warnings: false,
-      errors: true
-    },
-    before: require('./mock/mock-server.js')
-  },
-  configureWebpack: {
-    // provide the app's title in webpack's name field, so that
-    // it can be accessed in index.html to inject the correct title.
-    name: name,
-    resolve: {
-      alias: {
-        '@': resolve('src')
-      }
-    }
-  },
-  chainWebpack(config) {
-    // it can improve the speed of the first screen, it is recommended to turn on preload
-    config.plugin('preload').tap(() => [
-      {
-        rel: 'preload',
-        // to ignore runtime.js
-        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
-        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
-        include: 'initial'
-      }
-    ])
-
-    // when there are many pages, it will cause too many meaningless requests
-    config.plugins.delete('prefetch')
-
-    // set svg-sprite-loader
-    config.module
-      .rule('svg')
-      .exclude.add(resolve('src/icons'))
-      .end()
-    config.module
-      .rule('icons')
-      .test(/\.svg$/)
-      .include.add(resolve('src/icons'))
-      .end()
-      .use('svg-sprite-loader')
-      .loader('svg-sprite-loader')
-      .options({
-        symbolId: 'icon-[name]'
-      })
-      .end()
-
-    config
-      .when(process.env.NODE_ENV !== 'development',
-        config => {
-          config
-            .plugin('ScriptExtHtmlWebpackPlugin')
-            .after('html')
-            .use('script-ext-html-webpack-plugin', [{
-            // `runtime` must same as runtimeChunk name. default is `runtime`
-              inline: /runtime\..*\.js$/
-            }])
-            .end()
-          config
-            .optimization.splitChunks({
-              chunks: 'all',
-              cacheGroups: {
-                libs: {
-                  name: 'chunk-libs',
-                  test: /[\\/]node_modules[\\/]/,
-                  priority: 10,
-                  chunks: 'initial' // only package third parties that are initially dependent
-                },
-                elementUI: {
-                  name: 'chunk-elementUI', // split elementUI into a single package
-                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
-                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
-                },
-                commons: {
-                  name: 'chunk-commons',
-                  test: resolve('src/components'), // can customize your rules
-                  minChunks: 3, //  minimum common number
-                  priority: 5,
-                  reuseExistingChunk: true
-                }
-              }
-            })
-          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
-          config.optimization.runtimeChunk('single')
-        }
-      )
-  }
-}

+ 0 - 9
layui-demo/layui-demo.iml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 0
layui-demo/tmp.js


+ 0 - 0
element-demo/element-demo.iml → monkey/monkey.iml


+ 28 - 7
monkey/util.js

@@ -2,6 +2,27 @@ function sleep(time) {
     return new Promise((resolve) => setTimeout(resolve, time));
 }
 
+Date.prototype.format = function (fmt) {
+    var o = {
+        "M+": this.getMonth() + 1,                 //月份
+        "d+": this.getDate(),                    //日
+        "h+": this.getHours(),                   //小时
+        "m+": this.getMinutes(),                 //分
+        "s+": this.getSeconds(),                 //秒
+        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
+        "S": this.getMilliseconds()             //毫秒
+    };
+    if (/(y+)/.test(fmt)) {
+        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+    }
+    for (var k in o) {
+        if (new RegExp("(" + k + ")").test(fmt)) {
+            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+        }
+    }
+    return fmt;
+}
+
 async function getDom(sel) {
     for (let i = 0; i < 100; i++) {
         let dom = document.querySelector(sel);
@@ -188,12 +209,12 @@ function addJQ() {
  * @param text
  * @param uri
  */
-function copyTextToClipboard(text,uri) {
+function copyTextToClipboard(text, uri) {
     let copyFrom, agent, body;
 
     copyFrom = document.createElement("a");
-    copyFrom.setAttribute("id","target");
-    copyFrom.setAttribute("href",uri);
+    copyFrom.setAttribute("id", "target");
+    copyFrom.setAttribute("href", uri);
     copyFrom.innerHTML = text;
     agent = document.createElement("button");
     body = document.getElementsByTagName('body')[0];
@@ -201,16 +222,16 @@ function copyTextToClipboard(text,uri) {
     body.appendChild(agent);
     // 麻烦:无法传入'.btn'元素 我们可以创建一个btn作为代理
     let clipboard = new ClipboardJS(agent, {
-        target: function() {
+        target: function () {
             return document.querySelector('#target');
         }
     });
 
-    clipboard.on('success', function(e) {
+    clipboard.on('success', function (e) {
         console.log(e);
     });
 
-    clipboard.on('error', function(e) {
+    clipboard.on('error', function (e) {
         console.log(e);
     });
     agent.click();
@@ -228,4 +249,4 @@ function addLink(domSelector, link_str, linkUrl) {
     eleScript.innerHTML = link_str.replaceAll(" ", "&nbsp;");
     eleScript.href = linkUrl;
     document.querySelector(domSelector).appendChild(eleScript);
-}
+}

+ 180 - 0
simple-demo/bootstrapTest.html

@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>bootstrap - 增删改查</title>
+  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
+  <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+</head>
+<body>
+<!-- 表格 -->
+<div class="container" style="padding-top: 40px;">
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-8">
+        <input type="text" class="form-control swich" />
+      </div>
+      <div class="col-md-3">
+        <button class="btn btn-danger sreach">搜索</button>
+        <button class="btn btn-default add" data-toggle="modal" data-target="#myModel">增加</button>
+      </div>
+    </div>
+  </div>
+  <table class="table table-bordered text-center">
+    <tr>
+      <td>编号</td>
+      <td>姓名</td>
+      <td>成绩</td>
+      <td>操作</td>
+    </tr>
+    <tr>
+      <td>1</td>
+      <td>张三</td>
+      <td>89</td>
+      <td>
+        <button class="btn btn-primary rev" data-toggle="modal" data-target="#myModal">修改</button>
+        <button class="btn btn-danger del">删除</button>
+      </td>
+    </tr>
+    <tr>
+      <td>2</td>
+      <td>李四</td>
+      <td>91</td>
+      <td>
+        <button class="btn btn-primary rev" data-toggle="modal" data-target="#myModal">修改</button>
+        <button class="btn btn-danger del">删除</button>
+      </td>
+    </tr>
+    <tr>
+      <td>3</td>
+      <td>刘一</td>
+      <td>80</td>
+      <td>
+        <button class="btn btn-primary rev" data-toggle="modal" data-target="#myModal">修改</button>
+        <button class="btn btn-danger del">删除</button>
+      </td>
+    </tr>
+  </table>
+</div>
+<!-- 修改的模态框 -->
+<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title" id="myModalLabel">修改信息</h4>
+      </div>
+      <div class="modal-body">
+        <form>
+          <div class="form-group">
+            <input type="text" placeholder="编号" id="reusrnum" class="form-control" />
+          </div>
+          <div class="form-group">
+            <input type="text" placeholder="名字" id="reusrname" class="form-control" />
+          </div>
+          <div class="form-group">
+            <input type="text" placeholder="成绩" class="form-control" id="rescore" />
+          </div>
+        </form>
+
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+        <button type="button" class="btn btn-primary olk" data-dismiss="modal">提交更改</button>
+      </div>
+    </div>
+    <!-- /.modal-content -->
+  </div>
+  <!-- /.modal -->
+</div>
+<!-- 增加的模态框 -->
+<div class="modal fade" id="myModel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title" id="myModalLabel">增加信息</h4>
+      </div>
+      <div class="modal-body">
+        <form>
+          <div class="form-group">
+            <input type="text" placeholder="编号" id="reusrnum" class="form-control" />
+          </div>
+          <div class="form-group">
+            <input type="text" placeholder="名字" id="reusrname" class="form-control" />
+          </div>
+          <div class="form-group">
+            <input type="text" placeholder="成绩" class="form-control" id="rescore" />
+          </div>
+        </form>
+
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+        <button type="button" class="btn btn-primary aad" data-dismiss="modal">增加信息</button>
+      </div>
+    </div>
+    <!-- /.modal-content -->
+  </div>
+  <!-- /.modal -->
+</div>
+<script>
+
+  //删除的功能
+  $(document).on("click", ".del", function () {
+    $(this).parents("tr").remove()
+  })
+  //改的功能
+  var _this = null
+  $(document).on("click", ".rev", function () {
+    var _arr = []
+    _this = $(this).parents("tr")
+    $(this).parents("tr").find("td:not(:last)").each(function () {
+      _arr.push($(this).text())
+    })
+    $("#myModal").find("input").each(function (i) {
+      $(this).val(_arr[i])
+    })
+  })
+
+  $(document).on("click", ".olk", function () {
+    var _arr = []
+    $("#myModal").find("input").each(function () {
+      _arr.push($(this).val())
+    })
+    _this.find("td:not(:last)").each(function (i) {
+      $(this).text(_arr[i])
+    })
+  })
+  //增加的功能
+  $(document).on("click", ".aad", function () {
+    var _arr = []
+    var str = ""
+    $("#myModel").find("input").each(function () {
+      _arr.push($(this).val())
+
+    })
+
+    str = '<tr><td>' + _arr[0] + '</td><td>' + _arr[1] + '</td><td>' + _arr[2] + '</td><td><button class="btn btn-primary rev" data-toggle="modal" data-target="#myModal">修改</button> <button class="btn btn-danger del">删除</button></td></tr>'
+    $(".table").append(str)
+
+  })
+  //查的功能
+  $(".sreach").click(function () {
+    var oS = $(".swich").val()
+    if (oS.length == 0) {
+      alert("请输入点东西")
+    } else if ($("table tr td:contains('" + oS + "')").length == 0) {
+      alert("找不到数据")
+    } else {
+      $(".table tr:not(:first)").hide()
+      $(".table tr:contains('" + oS + "')").show().find("input").prop("checked", true)
+    }
+
+  })
+</script>
+</body>
+</html>

+ 166 - 0
simple-demo/history_list.html

@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <!--<meta name="viewport" content="width=device-width, initial-scale=1">-->
+    <script src="https://web.tianyunperfect.cn/util.js"></script>
+    <title>历史 URL 列表</title>
+    <script src="js/axios.min.js"></script>
+    <script src="js/vue.min.js"></script>
+    <script src="https://api.map.baidu.com/api?v=2.0&ak=WMYeXwq7z0VcaiUXTuYTGPZsm8Selmfd"></script>
+    <style>
+        .container {
+            width: 500px;
+            height: 50px;
+            margin: 20px auto;
+        }
+        .parent {
+            width: 100%;
+            height: 42px;
+            top: 4px;
+            position: relative;
+        }
+
+        .parent > input:first-of-type {
+            /*输入框高度设置为40px, border占据2px,总高度为42px*/
+            width: 380px;
+            height: 40px;
+            border: 1px solid #ccc;
+            font-size: 16px;
+            outline: none;
+        }
+
+        .parent > input:first-of-type:focus {
+            border: 1px solid #317ef3;
+            padding-left: 10px;
+        }
+
+        .parent > input:last-of-type {
+            /*button按钮border并不占据外围大小,设置高度42px*/
+            width: 100px;
+            height: 44px;
+            position: absolute;
+            background: #317ef3;
+            border: 1px solid #317ef3;
+            color: #fff;
+            font-size: 16px;
+            outline: none;
+        }
+    </style>
+</head>
+<body>
+<div id="tby">
+    <div class="container">
+        <form action="" class="parent">
+            <input type="text" v-model="msg">
+            <input type="button" value="搜索" @click="search">
+        </form>
+    </div>
+    <table>
+        <thead>
+        <tr>
+            <td>id</td>
+            <td>时间</td>
+            <td>网址</td>
+            <td>url</td>
+        </tr>
+        </thead>
+        <tbody>
+        <tr v-for="(item,index) in list">
+            <td>{{item.id}}</td>
+            <td>{{new Date(item.create_time).format("yyyy-MM-dd hh:mm:ss")}}</td>
+            <td>
+                <a :href="item.url"
+                   target="_blank">{{item.title}}</a>
+            </td>
+            <td>{{item.url}}</td>
+        </tr>
+        </tbody>
+    </table>
+    <!-- 分页按钮 -->
+    <div class="page-icon">
+        <button class="firstPage" @click="first_click">第一页</button>
+        <button class="beforePage" @click="prev_click">上一页</button>
+        <button>第<input v-model="page" @change="choose_page" type="text" value="1"/>页</button>
+        <button class="nextPage" @click="next_click">下一页</button>
+    </div>
+
+
+</div>
+
+
+<script>
+
+    Date.prototype.format = function (fmt) {
+        var o = {
+            "M+": this.getMonth() + 1,                 //月份
+            "d+": this.getDate(),                    //日
+            "h+": this.getHours(),                   //小时
+            "m+": this.getMinutes(),                 //分
+            "s+": this.getSeconds(),                 //秒
+            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
+            "S": this.getMilliseconds()             //毫秒
+        };
+        if (/(y+)/.test(fmt)) {
+            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+        }
+        for (var k in o) {
+            if (new RegExp("(" + k + ")").test(fmt)) {
+                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+            }
+        }
+        return fmt;
+    }
+
+    const scrollElement = (el) => {
+        document.querySelector(el).scrollIntoView({behavior: 'smooth'});
+    }
+
+    let _this = new Vue({
+        el: '#tby',
+        data: {
+            page: 1,
+            size: 30,
+            msg: "",
+            list: []
+        },
+        mounted: function () {
+            this.search();
+        },
+        methods: {
+            first_click: function () {
+                this.page = 1;
+                this.search();
+            },
+            prev_click: function () {
+                this.page -= 1;
+                this.search();
+            },
+            choose_page: function () {
+                this.search();
+            },
+            next_click: function () {
+                this.page += 1;
+                this.search();
+            },
+            getParam: function () {
+                let obj = {};
+                obj['title'] = this.msg;
+                obj['page'] = this.page;
+                obj['size'] = this.size;
+                return obj;
+            },
+            search: function () {
+                axios.get("https://api.tianyunperfect.cn/web_history/search", {params: this.getParam()}).then(res => {
+                    if (res.data.code === 1) {
+                        _this.list = res.data.data.list;
+                    }
+                });
+            }
+        }
+    });
+
+
+</script>
+</body>
+</html>

+ 3 - 3
simple-demo/index.html

@@ -65,8 +65,8 @@
         <div class="modal-dialog modal-dialog-centered" role="document">
             <div class="modal-content">
                 <div class="modal-header">
-                    <h5 class="modal-title" v-if="isUpdate">修改书籍</h5>
-                    <h5 class="modal-title" v-else>新增书籍</h5>
+                    <h5 class="modal-title" v-if="isUpdate">修改</h5>
+                    <h5 class="modal-title" v-else>新增</h5>
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                         <span aria-hidden="true">&times;</span>
                     </button>
@@ -125,7 +125,7 @@
             }
         },
         mounted: function () {
-            // this.queryList();
+            this.queryList();
         },
         methods: {
             modelShow() {

+ 75 - 15
simple-demo/location.html

@@ -2,11 +2,15 @@
 <html lang="en">
 <head>
     <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>location</title>
     <script src="js/axios.min.js"></script>
+    <script src="https://web.tianyunperfect.cn/util.js"></script>
+    <script src="https://api.map.baidu.com/api?v=2.0&ak=WMYeXwq7z0VcaiUXTuYTGPZsm8Selmfd"></script>
 </head>
 <body>
-<h1 id="msg"></h1>
+<textarea id="msg" style="width: 100%; font-size: 25px" rows="10"></textarea>
+<h1 id="tip">2秒内发送</h1>
 <script>
     Date.prototype.format = function (fmt) {
         var o = {
@@ -28,27 +32,83 @@
         }
         return fmt;
     }
-    navigator.geolocation.getCurrentPosition(function (position) {
-        let longitude = position.coords.longitude;
-        let latitude = position.coords.latitude;
+</script>
+<script>
+    let longitude;
+    let latitude;
+    let locationStr = '';
+    let status = false;
+
+    // 获取地址位置的名字
+    function getLocationStr() {
+        var map = new BMap.Map("l-map");
+        // 创建地理编码实例, 并配置参数获取乡镇级数据
+        var myGeo = new BMap.Geocoder({extensions_town: true});
+        // 根据坐标得到地址描述
+        myGeo.getLocation(new BMap.Point(longitude, latitude), function (result) {
+            if (result) {
+                locationStr = result.address;
+            } else {
+                return "未知";
+            }
+        });
+    }
+    // 获取经纬度
+    function getLocation() {
+        // 创建百度地理位置实例,代替 navigator.geolocation
+        var geolocation = new BMap.Geolocation();
+        geolocation.getCurrentPosition(function (e) {
+            if (this.getStatus() == BMAP_STATUS_SUCCESS) {
+                // 百度 geolocation 的经纬度属性不同,此处是 point.lat 而不是 coords.latitude
+                latitude = e.point.lat;
+                longitude = e.point.lng;
+                getLocationStr();
+            } else {
+            }
+        });
+    }
+
 
+    getLocation();
+
+    setTimeout(() => {
+        if (status === false) {
+            sendMsg();
+        }
+    }, 2000)
+
+    function setTip(str) {
+        document.querySelector('#tip').innerHTML = str;
+    }
+
+    document.querySelector("#msg").onfocus = function () {
+        status = true;
+        setTip('点击发送');
+        document.querySelector("#tip").onclick = function () {
+            sendMsg();
+        };
+    };
+
+    function sendMsg() {
         axios.post("https://api.tianyunperfect.cn/web_history/location_history", {
-            "location_str": "",
-            "location_xy": longitude + "-" + latitude,
-            "msg": "",
+            "location_str": locationStr,
+            "location_xy": latitude + "," + longitude,
+            "msg": document.querySelector("#msg").value,
             "create_time": new Date().format('yyyy-MM-dd hh:mm:ss'),
-            "update_time": new Date().format('yyyy-MM-dd hh:mm:ss')
+            "update_time": new Date().format('yyyy-MM-dd hh:mm:ss'),
+            "user_id": getQueryString("user_id")
         }).then(res => {
             if (res.data.code === 1) {
-                window.close();
-                document.querySelector("#msg").innerHTML = "OK";
+                // window.close();
+                if (longitude === undefined) {
+                    setTip("发送成功,但是没有经纬度");
+                } else {
+                    setTip("发送成功!!!!!!");
+                }
             }
         });
-    }, function (error) {
-        alert(error.message);
-    }, {
-        timeout: 90000
-    });
+    }
+
 </script>
 </body>
 </html>

+ 288 - 0
simple-demo/location_list.html

@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <!--<meta name="viewport" content="width=device-width, initial-scale=1">-->
+    <script src="https://web.tianyunperfect.cn/util.js"></script>
+    <title>location_list</title>
+    <script src="js/axios.min.js"></script>
+    <script src="js/vue.min.js"></script>
+    <script src="https://api.map.baidu.com/api?v=2.0&ak=WMYeXwq7z0VcaiUXTuYTGPZsm8Selmfd"></script>
+    <style>
+        .container {
+
+            width: 500px;
+
+            height: 50px;
+
+            margin: 20px auto;
+
+        }
+
+
+        .parent {
+
+            width: 100%;
+
+            height: 42px;
+
+            top: 4px;
+
+            position: relative;
+
+        }
+
+
+        .parent > input:first-of-type {
+
+            /*输入框高度设置为40px, border占据2px,总高度为42px*/
+
+            width: 380px;
+
+            height: 40px;
+
+            border: 1px solid #ccc;
+
+            font-size: 16px;
+
+            outline: none;
+
+        }
+
+
+        .parent > input:first-of-type:focus {
+
+            border: 1px solid #317ef3;
+
+            padding-left: 10px;
+
+        }
+
+        .parent > input:last-of-type {
+            /*button按钮border并不占据外围大小,设置高度42px*/
+            width: 100px;
+            height: 44px;
+            position: absolute;
+            background: #317ef3;
+            border: 1px solid #317ef3;
+            color: #fff;
+            font-size: 16px;
+            outline: none;
+        }
+    </style>
+</head>
+<body>
+<div id="tby">
+    <div class="container">
+        <form action="" class="parent">
+            <input type="text" v-model="msg">
+            <input type="button" value="搜索" @click="search">
+        </form>
+    </div>
+    <table>
+        <thead>
+        <tr>
+            <td>id</td>
+            <td>时间</td>
+            <td>经纬度</td>
+            <td>附加信息</td>
+            <td>猜测位置</td>
+            <td>与我大概距离</td>
+            <td>操作</td>
+        </tr>
+        </thead>
+        <tbody>
+        <tr v-for="(item,index) in list">
+            <td>{{item.id}}</td>
+            <td>{{new Date(item.create_time).format("yyyy-MM-dd hh:mm:ss")}}</td>
+            <td>
+                <a :href="'https://api.map.baidu.com/marker?location='+ item.location_xy + '&title=' + item.msg + '&content=&output=html&src=webapp.baidu.openAPIdemo'"
+                   target="_blank">{{item.location_xy}}</a>
+            </td>
+            <td>{{item.msg}}</td>
+            <td>{{item.location_str}}</td>
+            <td>{{item['distance']}}</td>
+            <td>
+                <span @click="to_update(item)">跳转更新</span>
+                <span> | | | | </span>
+                <span @click="delete_by_id(item.id)">删除</span>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+    <!-- 分页按钮 -->
+    <div class="page-icon">
+        <button class="firstPage" @click="first_click">第一页</button>
+        <button class="beforePage" @click="prev_click">上一页</button>
+        <button>第<input v-model="page" @change="choose_page" type="text" value="1"/>页</button>
+        <button class="nextPage" @click="next_click">下一页</button>
+    </div>
+
+
+    <hr>
+    <p>根据 id 更新</p>
+    <input v-model="update_id" placeholder="id" id="update_id">
+    <input v-model="update_msg" placeholder="信息">
+    <button @click="update">更新</button>
+
+
+</div>
+
+
+<script>
+
+    Date.prototype.format = function (fmt) {
+        var o = {
+            "M+": this.getMonth() + 1,                 //月份
+            "d+": this.getDate(),                    //日
+            "h+": this.getHours(),                   //小时
+            "m+": this.getMinutes(),                 //分
+            "s+": this.getSeconds(),                 //秒
+            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
+            "S": this.getMilliseconds()             //毫秒
+        };
+        if (/(y+)/.test(fmt)) {
+            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+        }
+        for (var k in o) {
+            if (new RegExp("(" + k + ")").test(fmt)) {
+                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+            }
+        }
+        return fmt;
+    }
+
+    const scrollElement = (el) => {
+        document.querySelector(el).scrollIntoView({behavior: 'smooth'});
+    }
+    let longitude = '';
+    let latitude;
+
+    // 获取经纬度
+    function getLocation() {
+        // 创建百度地理位置实例,代替 navigator.geolocation
+        var geolocation = new BMap.Geolocation();
+        geolocation.getCurrentPosition(function (e) {
+            if (this.getStatus() == BMAP_STATUS_SUCCESS) {
+                // 百度 geolocation 的经纬度属性不同,此处是 point.lat 而不是 coords.latitude
+                latitude = e.point.lat;
+                longitude = e.point.lng;
+
+                _this.updateLocationStr();
+            } else {
+            }
+        });
+    }
+
+    getLocation();
+
+    let _this = new Vue({
+        el: '#tby',
+        data: {
+            update_id: '',
+            update_msg: '',
+            page: 1,
+            size: 1000,
+            msg: "",
+            user_id: "",
+            list: []
+        },
+        mounted: function () {
+            this.user_id = getQueryString("user_id");
+            this.search();
+        },
+        methods: {
+            updateLocationStr() {
+                for (const item of _this.list) {
+                    if (item.location_xy.indexOf("un") < 0 && longitude.toString().length > 2) {
+                        let split = item.location_xy.split(",");
+                        item['distance'] = _this.getDistance(split[1], split[0], longitude, latitude);
+                    }
+                }
+                _this.$forceUpdate();
+            },
+            getDistance(lon1, lat1, lon2, lat2) {
+                const map = new BMap.Map("allmap");
+                const pointA = new BMap.Point(lon1, lat1);  // 创建点坐标A
+                const pointB = new BMap.Point(lon2, lat2);  // 创建点坐标B
+                const range = map.getDistance(pointA, pointB).toFixed(2);  //获取两点距离,保留小数点后两位
+                return range;
+            },
+            delete_by_id: function (id) {
+                if (confirm("确定要删除吗?不可恢复!!!")) {
+                    axios.get("https://api.tianyunperfect.cn/web_history/location_delete", {
+                        params: {
+                            "id": id,
+                            "user_id": _this.user_id,
+                        }
+                    }).then(res => {
+                        if (res.data.code === 1) {
+                            _this.search();
+                            _this.update_id = '';
+                            _this.update_msg = '';
+                        }
+                    });
+                }
+
+            },
+            to_update: function (item) {
+                this.update_id = item.id;
+                if (item.msg && item.msg.length > 1) {
+                    this.update_msg = item.msg;
+                }
+                scrollElement("#update_id");
+            },
+            update: function () {
+                axios.get("https://api.tianyunperfect.cn/web_history/location_update", {
+                    params: {
+                        "id": _this.update_id,
+                        "user_id": _this.user_id,
+                        "msg": _this.update_msg
+                    }
+                }).then(res => {
+                    if (res.data.code === 1) {
+                        _this.search();
+                        _this.update_id = '';
+                        _this.update_msg = '';
+                    }
+                });
+            },
+            first_click: function () {
+                this.page = 1;
+                this.search();
+            },
+            prev_click: function () {
+                this.page -= 1;
+                this.search();
+            },
+            choose_page: function () {
+                this.search();
+            },
+            next_click: function () {
+                this.page += 1;
+                this.search();
+            },
+            getParam: function () {
+                let obj = {};
+                obj['user_id'] = this.user_id;
+                obj['limit1'] = (this.page - 1) * this.size;
+                obj['limit2'] = this.page * this.size;
+                if (this.msg.length > 0) {
+                    obj["msg"] = this.msg;
+                }
+                return obj;
+            },
+            search: function () {
+                axios.get("https://api.tianyunperfect.cn/web_history/location_history", {params: this.getParam()}).then(res => {
+                    if (res.data.code === 1) {
+                        _this.list = res.data.data;
+                    }
+                });
+            }
+        }
+    });
+
+
+</script>
+</body>
+</html>

+ 0 - 11
tmp/calendar.html

@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>日历</title>
-</head>
-<body>
-<iframe id="api_iframe_bmcx" name="api_iframe_bmcx" src="https://www.bmcx.com/apiiframe/?api_from=bmcx&api_url=https://wannianrili.bmcx.com/&api_width=98%&api_backgroundcolor=FFFFFF&api_navigation=no" width="400" height="470" scrolling="no" frameborder="0"></iframe>
-
-</body>
-</html>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.