Bläddra i källkod

第三次

master
xiezhenghui 4 år sedan
förälder
incheckning
fb37d768cd
100 ändrade filer med 2805 tillägg och 13049 borttagningar
  1. 2
    9
      .babelrc
  2. 0
    0
      .eslintignore
  3. 21
    0
      .eslintrc.js
  4. 16
    2
      .gitignore
  5. 2
    7
      .postcssrc.js
  6. 5
    0
      .travis.yml
  7. 21
    0
      LICENSE
  8. 105
    11
      README.md
  9. 0
    41
      build/build.js
  10. 0
    54
      build/check-versions.js
  11. Binär
      build/logo.png
  12. 0
    101
      build/utils.js
  13. 0
    22
      build/vue-loader.conf.js
  14. 0
    86
      build/webpack.base.conf.js
  15. 0
    95
      build/webpack.dev.conf.js
  16. 0
    145
      build/webpack.prod.conf.js
  17. 0
    7
      config/dev.env.js
  18. 0
    69
      config/index.js
  19. 0
    4
      config/prod.env.js
  20. 3
    0
      cypress.json
  21. 0
    12
      index.html
  22. 0
    12318
      package-lock.json
  23. 58
    53
      package.json
  24. Binär
      public/favicon.ico
  25. 17
    0
      public/index.html
  26. 14
    13
      src/App.vue
  27. 51
    0
      src/api/data.js
  28. 11
    0
      src/api/routers.js
  29. 84
    0
      src/api/user.js
  30. 37
    0
      src/assets/icons/iconfont.css
  31. Binär
      src/assets/icons/iconfont.eot
  32. 56
    0
      src/assets/icons/iconfont.svg
  33. Binär
      src/assets/icons/iconfont.ttf
  34. Binär
      src/assets/icons/iconfont.woff
  35. 1
    0
      src/assets/images/error-page/error-401.svg
  36. 1
    0
      src/assets/images/error-page/error-404.svg
  37. 1
    0
      src/assets/images/error-page/error-500.svg
  38. Binär
      src/assets/images/icon-qr-qq-wechat.png
  39. 1
    0
      src/assets/images/icon-social-bilibili.svg
  40. 1
    0
      src/assets/images/icon-social-juejin.svg
  41. 1
    0
      src/assets/images/icon-social-twitter.svg
  42. 1
    0
      src/assets/images/icon-social-zhihu.svg
  43. Binär
      src/assets/images/login-bg.jpg
  44. Binär
      src/assets/images/logo-min.jpg
  45. Binär
      src/assets/images/logo.jpg
  46. Binär
      src/assets/images/talkingdata.png
  47. Binär
      src/assets/logo copy.png
  48. 58
    0
      src/components/charts/bar.vue
  49. 3
    0
      src/components/charts/index.js
  50. 70
    0
      src/components/charts/pie.vue
  51. 491
    0
      src/components/charts/theme.json
  52. 42
    0
      src/components/common-icon/common-icon.vue
  53. 2
    0
      src/components/common-icon/index.js
  54. 8
    0
      src/components/common/common.less
  55. 3
    0
      src/components/common/util.js
  56. 174
    0
      src/components/count-to/count-to.vue
  57. 2
    0
      src/components/count-to/index.js
  58. 10
    0
      src/components/count-to/index.less
  59. 2
    0
      src/components/cropper/index.js
  60. 35
    0
      src/components/cropper/index.less
  61. 139
    0
      src/components/cropper/index.vue
  62. 18
    0
      src/components/drag-drawer/drag-drawer-trigger.vue
  63. 156
    0
      src/components/drag-drawer/drag-drawer.vue
  64. 2
    0
      src/components/drag-drawer/index.js
  65. 70
    0
      src/components/drag-drawer/index.less
  66. 7
    0
      src/components/drag-drawer/mixin.js
  67. 92
    0
      src/components/drag-list/drag-list.vue
  68. 2
    0
      src/components/drag-list/index.js
  69. 75
    0
      src/components/editor/editor.vue
  70. 2
    0
      src/components/editor/index.js
  71. 35
    0
      src/components/icons/icons.vue
  72. 2
    0
      src/components/icons/index.js
  73. 2
    0
      src/components/info-card/index.js
  74. 94
    0
      src/components/info-card/infor-card.vue
  75. 2
    0
      src/components/login-form/index.js
  76. 72
    0
      src/components/login-form/login-form.vue
  77. 2
    0
      src/components/main/components/a-back-top/index.js
  78. 90
    0
      src/components/main/components/a-back-top/index.vue
  79. 49
    0
      src/components/main/components/error-store/error-store.vue
  80. 2
    0
      src/components/main/components/error-store/index.js
  81. 84
    0
      src/components/main/components/fullscreen/fullscreen.vue
  82. 2
    0
      src/components/main/components/fullscreen/index.js
  83. 4
    0
      src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less
  84. 46
    0
      src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue
  85. 2
    0
      src/components/main/components/header-bar/custom-bread-crumb/index.js
  86. 14
    0
      src/components/main/components/header-bar/header-bar.less
  87. 34
    0
      src/components/main/components/header-bar/header-bar.vue
  88. 2
    0
      src/components/main/components/header-bar/index.js
  89. 2
    0
      src/components/main/components/header-bar/sider-trigger/index.js
  90. 21
    0
      src/components/main/components/header-bar/sider-trigger/sider-trigger.less
  91. 27
    0
      src/components/main/components/header-bar/sider-trigger/sider-trigger.vue
  92. 2
    0
      src/components/main/components/language/index.js
  93. 51
    0
      src/components/main/components/language/language.vue
  94. 51
    0
      src/components/main/components/side-menu/collapsed-menu.vue
  95. 2
    0
      src/components/main/components/side-menu/index.js
  96. 21
    0
      src/components/main/components/side-menu/item-mixin.js
  97. 18
    0
      src/components/main/components/side-menu/mixin.js
  98. 26
    0
      src/components/main/components/side-menu/side-menu-item.vue
  99. 73
    0
      src/components/main/components/side-menu/side-menu.less
  100. 0
    0
      src/components/main/components/side-menu/side-menu.vue

+ 2
- 9
.babelrc Visa fil

@@ -1,12 +1,5 @@
1 1
 {
2 2
   "presets": [
3
-    ["env", {
4
-      "modules": false,
5
-      "targets": {
6
-        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7
-      }
8
-    }],
9
-    "stage-2"
10
-  ],
11
-  "plugins": ["transform-vue-jsx", "transform-runtime"]
3
+    "@vue/app"
4
+  ]
12 5
 }

static/.gitkeep → .eslintignore Visa fil


+ 21
- 0
.eslintrc.js Visa fil

@@ -0,0 +1,21 @@
1
+module.exports = {
2
+  root: true,
3
+  'extends': [
4
+    'plugin:vue/essential',
5
+    // '@vue/standard'
6
+  ],
7
+  rules: {
8
+    // allow async-await
9
+    'generator-star-spacing': 'off',
10
+    // allow debugger during development
11
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12
+    'vue/no-parsing-error': [2, {
13
+      'x-invalid-end-tag': false
14
+    }],
15
+    'no-undef': 'off',
16
+    'camelcase': 'off'
17
+  },
18
+  parserOptions: {
19
+    parser: 'babel-eslint'
20
+  }
21
+}

+ 16
- 2
.gitignore Visa fil

@@ -1,6 +1,17 @@
1 1
 .DS_Store
2
-node_modules/
3
-/dist/
2
+node_modules
3
+/dist
4
+
5
+package-lock.json
6
+
7
+/tests/e2e/videos/
8
+/tests/e2e/screenshots/
9
+
10
+# local env files
11
+.env.local
12
+.env.*.local
13
+
14
+# Log files
4 15
 npm-debug.log*
5 16
 yarn-debug.log*
6 17
 yarn-error.log*
@@ -12,3 +23,6 @@ yarn-error.log*
12 23
 *.ntvs*
13 24
 *.njsproj
14 25
 *.sln
26
+*.sw*
27
+
28
+build/env.js

+ 2
- 7
.postcssrc.js Visa fil

@@ -1,10 +1,5 @@
1
-// https://github.com/michael-ciniawsky/postcss-load-config
2
-
3 1
 module.exports = {
4
-  "plugins": {
5
-    "postcss-import": {},
6
-    "postcss-url": {},
7
-    // to edit target browsers: use "browserslist" field in package.json
8
-    "autoprefixer": {}
2
+  plugins: {
3
+    autoprefixer: {}
9 4
   }
10 5
 }

+ 5
- 0
.travis.yml Visa fil

@@ -0,0 +1,5 @@
1
+language: node_js
2
+node_js: stable
3
+script: npm run lint
4
+notifications:
5
+  email: false

+ 21
- 0
LICENSE Visa fil

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

+ 105
- 11
README.md Visa fil

@@ -1,21 +1,115 @@
1
-# mydemo
1
+<p align="center">
2
+    <a href="https://www.iviewui.com">
3
+        <img width="200" src="https://file.iviewui.com/logo-new.svg">
4
+    </a>
5
+</p>
2 6
 
3
-> A Vue.js project
7
+<h1>
8
+iView Admin
9
+    <h3>Vue.js 2.0 admin management system template based on iView.</h3>
10
+</h1>
4 11
 
5
-## Build Setup
12
+[![](https://img.shields.io/github/release/iview/iview-admin.svg)](https://github.com/iview/iview-admin/releases)
13
+[![](https://img.shields.io/travis/iview/iview-admin.svg?style=flat-square)](https://travis-ci.org/iview/iview-admin)
14
+[![vue](https://img.shields.io/badge/vue-2.5.17-brightgreen.svg?style=flat-square)](https://github.com/vuejs/vue)
15
+[![iview ui](https://img.shields.io/badge/iview-3.2.2-brightgreen.svg?style=flat-square)](https://github.com/iview/iview)
16
+[![npm](https://img.shields.io/npm/l/express.svg)]()
6 17
 
7
-``` bash
8
-# install dependencies
18
+<h2 align="center">Special Sponsors</h2>
19
+<table>
20
+      <tbody>
21
+        <tr>
22
+          <td align="center" valign="middle">
23
+            <a href="https://segmentfault.com/ls/1650000016424063" target="_blank">
24
+              <img width="300" src="https://file.iviewui.com/asd/asd-i-2.png">
25
+            </a>
26
+          </td>
27
+          <td align="center" valign="middle">
28
+            <a href="https://e.coding.net/?utm_source=iview" target="_blank">
29
+              <img width="300" src="https://file.iviewui.com/asd/asd-coding4.png">
30
+            </a>
31
+          </td>
32
+            <td align="center" valign="middle">
33
+            <a href="https://cn.udacity.com/fend/?utm_source=iviewui&utm_medium=banner&utm_campaign=fend" target="_blank">
34
+              <img width="300" src="https://file.iviewui.com/asd/asd-u-new-2.png">
35
+            </a>
36
+          </td>
37
+        </tr>
38
+      </tbody>
39
+</table>
40
+
41
+> If you'd like be a sponsor, to show your ads in GitHub and iView doc, please email admin@aresn.com to get more infomation.
42
+
43
+## Introduction
44
+
45
+iView Admin is a front-end management background integration solution. It based on [Vue.js](https://github.com/vuejs/vue) and use the UI Toolkit [iView](https://github.com/iview/iview).
46
+
47
+- [Document](https://lison16.github.io/iview-admin-doc/)
48
+- [Preview](https://admin.iviewui.com/)
49
+- [Base template recommends using](https://github.com/iview/iview-admin/tree/template)
50
+
51
+![image](https://file.iviewui.com/admin-dist/admin-preview.png)
52
+
53
+## Features
54
+
55
+- Login / Logout
56
+- Permission Authentication
57
+    - A list of filters
58
+    - Permission to switch
59
+- i18n
60
+- Components
61
+    - Rich Text Editor
62
+    - Markdown Editor
63
+    - City Cascader
64
+    - Photos preview and edit
65
+    - Draggable list
66
+    - File upload
67
+    - Digital gradient
68
+    - split-pane
69
+- Form
70
+    - The article published
71
+    - Workflow
72
+- Table
73
+    - Drag-and-drop sort
74
+    - Searchable form
75
+    - Table export data
76
+        - Export to Csv file
77
+        - Export to Xls file
78
+    - Table to picture
79
+- Error Page
80
+    - 403
81
+    - 404
82
+    - 500
83
+- Router
84
+    - Dynamic routing
85
+    - With reference page
86
+- Theme
87
+- Shrink the sidebar
88
+- Tag navigation
89
+- Breadcrumb navigation
90
+- Full screen / exit full screen
91
+- Lock screen
92
+- The message center
93
+- Personal center
94
+
95
+## Getting started
96
+```bush
97
+# clone the project
98
+git clone https://github.com/iview/iview-admin.git
99
+
100
+// install dependencies
9 101
 npm install
10 102
 
11
-# serve with hot reload at localhost:8080
103
+// develop
12 104
 npm run dev
105
+```
13 106
 
14
-# build for production with minification
107
+## Build
108
+```bush
15 109
 npm run build
16
-
17
-# build for production and view the bundle analyzer report
18
-npm run build --report
19 110
 ```
20 111
 
21
-For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
112
+## License
113
+[MIT](http://opensource.org/licenses/MIT)
114
+
115
+Copyright (c) 2016-present, iView

+ 0
- 41
build/build.js Visa fil

@@ -1,41 +0,0 @@
1
-'use strict'
2
-require('./check-versions')()
3
-
4
-process.env.NODE_ENV = 'production'
5
-
6
-const ora = require('ora')
7
-const rm = require('rimraf')
8
-const path = require('path')
9
-const chalk = require('chalk')
10
-const webpack = require('webpack')
11
-const config = require('../config')
12
-const webpackConfig = require('./webpack.prod.conf')
13
-
14
-const spinner = ora('building for production...')
15
-spinner.start()
16
-
17
-rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18
-  if (err) throw err
19
-  webpack(webpackConfig, (err, stats) => {
20
-    spinner.stop()
21
-    if (err) throw err
22
-    process.stdout.write(stats.toString({
23
-      colors: true,
24
-      modules: false,
25
-      children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26
-      chunks: false,
27
-      chunkModules: false
28
-    }) + '\n\n')
29
-
30
-    if (stats.hasErrors()) {
31
-      console.log(chalk.red('  Build failed with errors.\n'))
32
-      process.exit(1)
33
-    }
34
-
35
-    console.log(chalk.cyan('  Build complete.\n'))
36
-    console.log(chalk.yellow(
37
-      '  Tip: built files are meant to be served over an HTTP server.\n' +
38
-      '  Opening index.html over file:// won\'t work.\n'
39
-    ))
40
-  })
41
-})

+ 0
- 54
build/check-versions.js Visa fil

@@ -1,54 +0,0 @@
1
-'use strict'
2
-const chalk = require('chalk')
3
-const semver = require('semver')
4
-const packageConfig = require('../package.json')
5
-const shell = require('shelljs')
6
-
7
-function exec (cmd) {
8
-  return require('child_process').execSync(cmd).toString().trim()
9
-}
10
-
11
-const versionRequirements = [
12
-  {
13
-    name: 'node',
14
-    currentVersion: semver.clean(process.version),
15
-    versionRequirement: packageConfig.engines.node
16
-  }
17
-]
18
-
19
-if (shell.which('npm')) {
20
-  versionRequirements.push({
21
-    name: 'npm',
22
-    currentVersion: exec('npm --version'),
23
-    versionRequirement: packageConfig.engines.npm
24
-  })
25
-}
26
-
27
-module.exports = function () {
28
-  const warnings = []
29
-
30
-  for (let i = 0; i < versionRequirements.length; i++) {
31
-    const mod = versionRequirements[i]
32
-
33
-    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34
-      warnings.push(mod.name + ': ' +
35
-        chalk.red(mod.currentVersion) + ' should be ' +
36
-        chalk.green(mod.versionRequirement)
37
-      )
38
-    }
39
-  }
40
-
41
-  if (warnings.length) {
42
-    console.log('')
43
-    console.log(chalk.yellow('To use this template, you must update following to modules:'))
44
-    console.log()
45
-
46
-    for (let i = 0; i < warnings.length; i++) {
47
-      const warning = warnings[i]
48
-      console.log('  ' + warning)
49
-    }
50
-
51
-    console.log()
52
-    process.exit(1)
53
-  }
54
-}

Binär
build/logo.png Visa fil


+ 0
- 101
build/utils.js Visa fil

@@ -1,101 +0,0 @@
1
-'use strict'
2
-const path = require('path')
3
-const config = require('../config')
4
-const ExtractTextPlugin = require('extract-text-webpack-plugin')
5
-const packageConfig = require('../package.json')
6
-
7
-exports.assetsPath = function (_path) {
8
-  const assetsSubDirectory = process.env.NODE_ENV === 'production'
9
-    ? config.build.assetsSubDirectory
10
-    : config.dev.assetsSubDirectory
11
-
12
-  return path.posix.join(assetsSubDirectory, _path)
13
-}
14
-
15
-exports.cssLoaders = function (options) {
16
-  options = options || {}
17
-
18
-  const cssLoader = {
19
-    loader: 'css-loader',
20
-    options: {
21
-      sourceMap: options.sourceMap
22
-    }
23
-  }
24
-
25
-  const postcssLoader = {
26
-    loader: 'postcss-loader',
27
-    options: {
28
-      sourceMap: options.sourceMap
29
-    }
30
-  }
31
-
32
-  // generate loader string to be used with extract text plugin
33
-  function generateLoaders (loader, loaderOptions) {
34
-    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35
-
36
-    if (loader) {
37
-      loaders.push({
38
-        loader: loader + '-loader',
39
-        options: Object.assign({}, loaderOptions, {
40
-          sourceMap: options.sourceMap
41
-        })
42
-      })
43
-    }
44
-
45
-    // Extract CSS when that option is specified
46
-    // (which is the case during production build)
47
-    if (options.extract) {
48
-      return ExtractTextPlugin.extract({
49
-        use: loaders,
50
-        fallback: 'vue-style-loader'
51
-      })
52
-    } else {
53
-      return ['vue-style-loader'].concat(loaders)
54
-    }
55
-  }
56
-
57
-  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58
-  return {
59
-    css: generateLoaders(),
60
-    postcss: generateLoaders(),
61
-    less: generateLoaders('less'),
62
-    sass: generateLoaders('sass', { indentedSyntax: true }),
63
-    scss: generateLoaders('sass'),
64
-    stylus: generateLoaders('stylus'),
65
-    styl: generateLoaders('stylus')
66
-  }
67
-}
68
-
69
-// Generate loaders for standalone style files (outside of .vue)
70
-exports.styleLoaders = function (options) {
71
-  const output = []
72
-  const loaders = exports.cssLoaders(options)
73
-
74
-  for (const extension in loaders) {
75
-    const loader = loaders[extension]
76
-    output.push({
77
-      test: new RegExp('\\.' + extension + '$'),
78
-      use: loader
79
-    })
80
-  }
81
-
82
-  return output
83
-}
84
-
85
-exports.createNotifierCallback = () => {
86
-  const notifier = require('node-notifier')
87
-
88
-  return (severity, errors) => {
89
-    if (severity !== 'error') return
90
-
91
-    const error = errors[0]
92
-    const filename = error.file && error.file.split('!').pop()
93
-
94
-    notifier.notify({
95
-      title: packageConfig.name,
96
-      message: severity + ': ' + error.name,
97
-      subtitle: filename || '',
98
-      icon: path.join(__dirname, 'logo.png')
99
-    })
100
-  }
101
-}

+ 0
- 22
build/vue-loader.conf.js Visa fil

@@ -1,22 +0,0 @@
1
-'use strict'
2
-const utils = require('./utils')
3
-const config = require('../config')
4
-const isProduction = process.env.NODE_ENV === 'production'
5
-const sourceMapEnabled = isProduction
6
-  ? config.build.productionSourceMap
7
-  : config.dev.cssSourceMap
8
-
9
-module.exports = {
10
-  loaders: utils.cssLoaders({
11
-    sourceMap: sourceMapEnabled,
12
-    extract: isProduction
13
-  }),
14
-  cssSourceMap: sourceMapEnabled,
15
-  cacheBusting: config.dev.cacheBusting,
16
-  transformToRequire: {
17
-    video: ['src', 'poster'],
18
-    source: 'src',
19
-    img: 'src',
20
-    image: 'xlink:href'
21
-  }
22
-}

+ 0
- 86
build/webpack.base.conf.js Visa fil

@@ -1,86 +0,0 @@
1
-'use strict'
2
-const path = require('path')
3
-const utils = require('./utils')
4
-const config = require('../config')
5
-const vueLoaderConfig = require('./vue-loader.conf')
6
-
7
-function resolve (dir) {
8
-  return path.join(__dirname, '..', dir)
9
-}
10
-
11
-
12
-
13
-module.exports = {
14
-  context: path.resolve(__dirname, '../'),
15
-  entry: {
16
-    app: './src/main.js'
17
-  },
18
-  output: {
19
-    path: config.build.assetsRoot,
20
-    filename: '[name].js',
21
-    publicPath: process.env.NODE_ENV === 'production'
22
-      ? config.build.assetsPublicPath
23
-      : config.dev.assetsPublicPath
24
-  },
25
-  resolve: {
26
-    extensions: ['.js', '.vue', '.json'],
27
-    alias: {
28
-      'vue$': 'vue/dist/vue.esm.js',
29
-      '@': resolve('src'),
30
-    }
31
-  },
32
-  module: {
33
-    rules: [
34
-      {
35
-        test: /\.less$/,
36
-        loader: 'style-loader!css-loader!less-loader'
37
-      },
38
-      {
39
-        test: /\.vue$/,
40
-        loader: 'vue-loader',
41
-        options: vueLoaderConfig
42
-      },
43
-      {
44
-        test: /\.js$/,
45
-        loader: 'babel-loader',
46
-        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
47
-      },
48
-      {
49
-        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
50
-        loader: 'url-loader',
51
-        options: {
52
-          limit: 10000,
53
-          name: utils.assetsPath('img/[name].[hash:7].[ext]')
54
-        }
55
-      },
56
-      {
57
-        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
58
-        loader: 'url-loader',
59
-        options: {
60
-          limit: 10000,
61
-          name: utils.assetsPath('media/[name].[hash:7].[ext]')
62
-        }
63
-      },
64
-      {
65
-        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
66
-        loader: 'url-loader',
67
-        options: {
68
-          limit: 10000,
69
-          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
70
-        }
71
-      }
72
-    ]
73
-  },
74
-  node: {
75
-    // prevent webpack from injecting useless setImmediate polyfill because Vue
76
-    // source contains it (although only uses it if it's native).
77
-    setImmediate: false,
78
-    // prevent webpack from injecting mocks to Node native modules
79
-    // that does not make sense for the client
80
-    dgram: 'empty',
81
-    fs: 'empty',
82
-    net: 'empty',
83
-    tls: 'empty',
84
-    child_process: 'empty'
85
-  }
86
-}

+ 0
- 95
build/webpack.dev.conf.js Visa fil

@@ -1,95 +0,0 @@
1
-'use strict'
2
-const utils = require('./utils')
3
-const webpack = require('webpack')
4
-const config = require('../config')
5
-const merge = require('webpack-merge')
6
-const path = require('path')
7
-const baseWebpackConfig = require('./webpack.base.conf')
8
-const CopyWebpackPlugin = require('copy-webpack-plugin')
9
-const HtmlWebpackPlugin = require('html-webpack-plugin')
10
-const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11
-const portfinder = require('portfinder')
12
-
13
-const HOST = process.env.HOST
14
-const PORT = process.env.PORT && Number(process.env.PORT)
15
-
16
-const devWebpackConfig = merge(baseWebpackConfig, {
17
-  module: {
18
-    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
19
-  },
20
-  // cheap-module-eval-source-map is faster for development
21
-  devtool: config.dev.devtool,
22
-
23
-  // these devServer options should be customized in /config/index.js
24
-  devServer: {
25
-    clientLogLevel: 'warning',
26
-    historyApiFallback: {
27
-      rewrites: [
28
-        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
29
-      ],
30
-    },
31
-    hot: true,
32
-    contentBase: false, // since we use CopyWebpackPlugin.
33
-    compress: true,
34
-    host: HOST || config.dev.host,
35
-    port: PORT || config.dev.port,
36
-    open: config.dev.autoOpenBrowser,
37
-    overlay: config.dev.errorOverlay
38
-      ? { warnings: false, errors: true }
39
-      : false,
40
-    publicPath: config.dev.assetsPublicPath,
41
-    proxy: config.dev.proxyTable,
42
-    quiet: true, // necessary for FriendlyErrorsPlugin
43
-    watchOptions: {
44
-      poll: config.dev.poll,
45
-    }
46
-  },
47
-  plugins: [
48
-    new webpack.DefinePlugin({
49
-      'process.env': require('../config/dev.env')
50
-    }),
51
-    new webpack.HotModuleReplacementPlugin(),
52
-    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
53
-    new webpack.NoEmitOnErrorsPlugin(),
54
-    // https://github.com/ampedandwired/html-webpack-plugin
55
-    new HtmlWebpackPlugin({
56
-      filename: 'index.html',
57
-      template: 'index.html',
58
-      inject: true
59
-    }),
60
-    // copy custom static assets
61
-    new CopyWebpackPlugin([
62
-      {
63
-        from: path.resolve(__dirname, '../static'),
64
-        to: config.dev.assetsSubDirectory,
65
-        ignore: ['.*']
66
-      }
67
-    ])
68
-  ]
69
-})
70
-
71
-module.exports = new Promise((resolve, reject) => {
72
-  portfinder.basePort = process.env.PORT || config.dev.port
73
-  portfinder.getPort((err, port) => {
74
-    if (err) {
75
-      reject(err)
76
-    } else {
77
-      // publish the new Port, necessary for e2e tests
78
-      process.env.PORT = port
79
-      // add port to devServer config
80
-      devWebpackConfig.devServer.port = port
81
-
82
-      // Add FriendlyErrorsPlugin
83
-      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
84
-        compilationSuccessInfo: {
85
-          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
86
-        },
87
-        onErrors: config.dev.notifyOnErrors
88
-        ? utils.createNotifierCallback()
89
-        : undefined
90
-      }))
91
-
92
-      resolve(devWebpackConfig)
93
-    }
94
-  })
95
-})

+ 0
- 145
build/webpack.prod.conf.js Visa fil

@@ -1,145 +0,0 @@
1
-'use strict'
2
-const path = require('path')
3
-const utils = require('./utils')
4
-const webpack = require('webpack')
5
-const config = require('../config')
6
-const merge = require('webpack-merge')
7
-const baseWebpackConfig = require('./webpack.base.conf')
8
-const CopyWebpackPlugin = require('copy-webpack-plugin')
9
-const HtmlWebpackPlugin = require('html-webpack-plugin')
10
-const ExtractTextPlugin = require('extract-text-webpack-plugin')
11
-const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
13
-
14
-const env = require('../config/prod.env')
15
-
16
-const webpackConfig = merge(baseWebpackConfig, {
17
-  module: {
18
-    rules: utils.styleLoaders({
19
-      sourceMap: config.build.productionSourceMap,
20
-      extract: true,
21
-      usePostCSS: true
22
-    })
23
-  },
24
-  devtool: config.build.productionSourceMap ? config.build.devtool : false,
25
-  output: {
26
-    path: config.build.assetsRoot,
27
-    filename: utils.assetsPath('js/[name].[chunkhash].js'),
28
-    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
29
-  },
30
-  plugins: [
31
-    // http://vuejs.github.io/vue-loader/en/workflow/production.html
32
-    new webpack.DefinePlugin({
33
-      'process.env': env
34
-    }),
35
-    new UglifyJsPlugin({
36
-      uglifyOptions: {
37
-        compress: {
38
-          warnings: false
39
-        }
40
-      },
41
-      sourceMap: config.build.productionSourceMap,
42
-      parallel: true
43
-    }),
44
-    // extract css into its own file
45
-    new ExtractTextPlugin({
46
-      filename: utils.assetsPath('css/[name].[contenthash].css'),
47
-      // Setting the following option to `false` will not extract CSS from codesplit chunks.
48
-      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
49
-      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
50
-      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
51
-      allChunks: true,
52
-    }),
53
-    // Compress extracted CSS. We are using this plugin so that possible
54
-    // duplicated CSS from different components can be deduped.
55
-    new OptimizeCSSPlugin({
56
-      cssProcessorOptions: config.build.productionSourceMap
57
-        ? { safe: true, map: { inline: false } }
58
-        : { safe: true }
59
-    }),
60
-    // generate dist index.html with correct asset hash for caching.
61
-    // you can customize output by editing /index.html
62
-    // see https://github.com/ampedandwired/html-webpack-plugin
63
-    new HtmlWebpackPlugin({
64
-      filename: config.build.index,
65
-      template: 'index.html',
66
-      inject: true,
67
-      minify: {
68
-        removeComments: true,
69
-        collapseWhitespace: true,
70
-        removeAttributeQuotes: true
71
-        // more options:
72
-        // https://github.com/kangax/html-minifier#options-quick-reference
73
-      },
74
-      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
75
-      chunksSortMode: 'dependency'
76
-    }),
77
-    // keep module.id stable when vendor modules does not change
78
-    new webpack.HashedModuleIdsPlugin(),
79
-    // enable scope hoisting
80
-    new webpack.optimize.ModuleConcatenationPlugin(),
81
-    // split vendor js into its own file
82
-    new webpack.optimize.CommonsChunkPlugin({
83
-      name: 'vendor',
84
-      minChunks (module) {
85
-        // any required modules inside node_modules are extracted to vendor
86
-        return (
87
-          module.resource &&
88
-          /\.js$/.test(module.resource) &&
89
-          module.resource.indexOf(
90
-            path.join(__dirname, '../node_modules')
91
-          ) === 0
92
-        )
93
-      }
94
-    }),
95
-    // extract webpack runtime and module manifest to its own file in order to
96
-    // prevent vendor hash from being updated whenever app bundle is updated
97
-    new webpack.optimize.CommonsChunkPlugin({
98
-      name: 'manifest',
99
-      minChunks: Infinity
100
-    }),
101
-    // This instance extracts shared chunks from code splitted chunks and bundles them
102
-    // in a separate chunk, similar to the vendor chunk
103
-    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
104
-    new webpack.optimize.CommonsChunkPlugin({
105
-      name: 'app',
106
-      async: 'vendor-async',
107
-      children: true,
108
-      minChunks: 3
109
-    }),
110
-
111
-    // copy custom static assets
112
-    new CopyWebpackPlugin([
113
-      {
114
-        from: path.resolve(__dirname, '../static'),
115
-        to: config.build.assetsSubDirectory,
116
-        ignore: ['.*']
117
-      }
118
-    ])
119
-  ]
120
-})
121
-
122
-if (config.build.productionGzip) {
123
-  const CompressionWebpackPlugin = require('compression-webpack-plugin')
124
-
125
-  webpackConfig.plugins.push(
126
-    new CompressionWebpackPlugin({
127
-      asset: '[path].gz[query]',
128
-      algorithm: 'gzip',
129
-      test: new RegExp(
130
-        '\\.(' +
131
-        config.build.productionGzipExtensions.join('|') +
132
-        ')$'
133
-      ),
134
-      threshold: 10240,
135
-      minRatio: 0.8
136
-    })
137
-  )
138
-}
139
-
140
-if (config.build.bundleAnalyzerReport) {
141
-  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
142
-  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
143
-}
144
-
145
-module.exports = webpackConfig

+ 0
- 7
config/dev.env.js Visa fil

@@ -1,7 +0,0 @@
1
-'use strict'
2
-const merge = require('webpack-merge')
3
-const prodEnv = require('./prod.env')
4
-
5
-module.exports = merge(prodEnv, {
6
-  NODE_ENV: '"development"'
7
-})

+ 0
- 69
config/index.js Visa fil

@@ -1,69 +0,0 @@
1
-'use strict'
2
-// Template version: 1.3.1
3
-// see http://vuejs-templates.github.io/webpack for documentation.
4
-
5
-const path = require('path')
6
-
7
-module.exports = {
8
-  dev: {
9
-
10
-    // Paths
11
-    assetsSubDirectory: 'static',
12
-    assetsPublicPath: '/',
13
-    proxyTable: {},
14
-
15
-    // Various Dev Server settings
16
-    host: 'localhost', // can be overwritten by process.env.HOST
17
-    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18
-    autoOpenBrowser: false,
19
-    errorOverlay: true,
20
-    notifyOnErrors: true,
21
-    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22
-
23
-    
24
-    /**
25
-     * Source Maps
26
-     */
27
-
28
-    // https://webpack.js.org/configuration/devtool/#development
29
-    devtool: 'cheap-module-eval-source-map',
30
-
31
-    // If you have problems debugging vue-files in devtools,
32
-    // set this to false - it *may* help
33
-    // https://vue-loader.vuejs.org/en/options.html#cachebusting
34
-    cacheBusting: true,
35
-
36
-    cssSourceMap: true
37
-  },
38
-
39
-  build: {
40
-    // Template for index.html
41
-    index: path.resolve(__dirname, '../dist/index.html'),
42
-
43
-    // Paths
44
-    assetsRoot: path.resolve(__dirname, '../dist'),
45
-    assetsSubDirectory: 'static',
46
-    assetsPublicPath: '/',
47
-
48
-    /**
49
-     * Source Maps
50
-     */
51
-
52
-    productionSourceMap: true,
53
-    // https://webpack.js.org/configuration/devtool/#production
54
-    devtool: '#source-map',
55
-
56
-    // Gzip off by default as many popular static hosts such as
57
-    // Surge or Netlify already gzip all static assets for you.
58
-    // Before setting to `true`, make sure to:
59
-    // npm install --save-dev compression-webpack-plugin
60
-    productionGzip: false,
61
-    productionGzipExtensions: ['js', 'css'],
62
-
63
-    // Run the build command with an extra argument to
64
-    // View the bundle analyzer report after build finishes:
65
-    // `npm run build --report`
66
-    // Set to `true` or `false` to always turn it on or off
67
-    bundleAnalyzerReport: process.env.npm_config_report
68
-  }
69
-}

+ 0
- 4
config/prod.env.js Visa fil

@@ -1,4 +0,0 @@
1
-'use strict'
2
-module.exports = {
3
-  NODE_ENV: '"production"'
4
-}

+ 3
- 0
cypress.json Visa fil

@@ -0,0 +1,3 @@
1
+{
2
+  "pluginsFile": "tests/e2e/plugins/index.js"
3
+}

+ 0
- 12
index.html Visa fil

@@ -1,12 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
-  <head>
4
-    <meta charset="utf-8">
5
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
-    <title>mydemo</title>
7
-  </head>
8
-  <body>
9
-    <div id="app"></div>
10
-    <!-- built files will be auto injected -->
11
-  </body>
12
-</html>

+ 0
- 12318
package-lock.json
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 58
- 53
package.json Visa fil

@@ -1,65 +1,70 @@
1 1
 {
2
-  "name": "mydemo",
3
-  "version": "1.0.0",
4
-  "description": "A Vue.js project",
5
-  "author": "lipenghui <1040605621@qq.com>",
6
-  "private": true,
2
+  "name": "iview-admin",
3
+  "version": "2.0.0",
4
+  "author": "Lison<lison16new@163.com>",
5
+  "private": false,
7 6
   "scripts": {
8
-    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9
-    "start": "npm run dev",
10
-    "build": "node build/build.js"
7
+    "dev": "vue-cli-service serve --open",
8
+    "build": "vue-cli-service build",
9
+    "lint": "vue-cli-service lint",
10
+    "test:unit": "vue-cli-service test:unit",
11
+    "test:e2e": "vue-cli-service test:e2e"
11 12
   },
12 13
   "dependencies": {
13
-    "less": "^3.9.0",
14
-    "less-loader": "^5.0.0",
15
-    "view-design": "^4.2.0",
16
-    "vue": "^2.5.2",
17
-    "vue-router": "^3.0.1"
14
+    "axios": "^0.18.0",
15
+    "clipboard": "^2.0.0",
16
+    "codemirror": "^5.38.0",
17
+    "countup": "^1.8.2",
18
+    "cropperjs": "^1.2.2",
19
+    "dayjs": "^1.7.7",
20
+    "echarts": "^4.0.4",
21
+    "html2canvas": "^1.0.0-alpha.12",
22
+    "iview": "^3.2.2",
23
+    "iview-area": "^1.5.17",
24
+    "js-cookie": "^2.2.0",
25
+    "simplemde": "^1.11.2",
26
+    "sortablejs": "^1.7.0",
27
+    "tree-table-vue": "^1.1.0",
28
+    "v-org-tree": "^1.0.6",
29
+    "vue": "^2.5.10",
30
+    "vue-i18n": "^7.8.0",
31
+    "vue-router": "^3.0.1",
32
+    "vuedraggable": "^2.16.0",
33
+    "vuex": "^3.0.1",
34
+    "wangeditor": "^3.1.1",
35
+    "xlsx": "^0.13.3"
18 36
   },
19 37
   "devDependencies": {
20
-    "autoprefixer": "^7.1.2",
21
-    "babel-core": "^6.22.1",
22
-    "babel-helper-vue-jsx-merge-props": "^2.0.3",
23
-    "babel-loader": "^7.1.1",
24
-    "babel-plugin-syntax-jsx": "^6.18.0",
25
-    "babel-plugin-transform-runtime": "^6.22.0",
26
-    "babel-plugin-transform-vue-jsx": "^3.5.0",
27
-    "babel-preset-env": "^1.3.2",
28
-    "babel-preset-stage-2": "^6.22.0",
29
-    "chalk": "^2.0.1",
30
-    "copy-webpack-plugin": "^4.0.1",
31
-    "css-loader": "^0.28.0",
32
-    "extract-text-webpack-plugin": "^3.0.0",
33
-    "file-loader": "^1.1.4",
34
-    "friendly-errors-webpack-plugin": "^1.6.1",
35
-    "html-webpack-plugin": "^2.30.1",
36
-    "node-notifier": "^5.1.2",
37
-    "optimize-css-assets-webpack-plugin": "^3.2.0",
38
-    "ora": "^1.2.0",
39
-    "portfinder": "^1.0.13",
40
-    "postcss-import": "^11.0.0",
41
-    "postcss-loader": "^2.0.8",
42
-    "postcss-url": "^7.2.1",
43
-    "rimraf": "^2.6.0",
44
-    "semver": "^5.3.0",
45
-    "shelljs": "^0.7.6",
46
-    "uglifyjs-webpack-plugin": "^1.1.1",
47
-    "url-loader": "^0.5.8",
48
-    "vue-loader": "^13.3.0",
49
-    "vue-style-loader": "^3.0.1",
50
-    "vue-template-compiler": "^2.5.2",
51
-    "webpack": "^3.6.0",
52
-    "webpack-bundle-analyzer": "^2.9.0",
53
-    "webpack-dev-server": "^2.9.1",
54
-    "webpack-merge": "^4.1.0"
55
-  },
56
-  "engines": {
57
-    "node": ">= 6.0.0",
58
-    "npm": ">= 3.0.0"
38
+    "@vue/cli-plugin-babel": "^3.0.1",
39
+    "@vue/cli-plugin-eslint": "^3.0.1",
40
+    "@vue/cli-plugin-unit-mocha": "^3.0.1",
41
+    "@vue/cli-service": "^3.0.1",
42
+    "@vue/eslint-config-standard": "^3.0.0-beta.10",
43
+    "@vue/test-utils": "^1.0.0-beta.10",
44
+    "chai": "^4.1.2",
45
+    "eslint-plugin-cypress": "^2.0.1",
46
+    "less": "^2.7.3",
47
+    "less-loader": "^4.0.5",
48
+    "lint-staged": "^6.0.0",
49
+    "mockjs": "^1.0.1-beta3",
50
+    "vue-template-compiler": "^2.5.13"
59 51
   },
60 52
   "browserslist": [
61 53
     "> 1%",
62 54
     "last 2 versions",
63 55
     "not ie <= 8"
64
-  ]
56
+  ],
57
+  "gitHooks": {
58
+    "pre-commit": "lint-staged"
59
+  },
60
+  "lint-staged": {
61
+    "*.js": [
62
+      "vue-cli-service lint",
63
+      "git add"
64
+    ],
65
+    "*.vue": [
66
+      "vue-cli-service lint",
67
+      "git add"
68
+    ]
69
+  }
65 70
 }

Binär
public/favicon.ico Visa fil


+ 17
- 0
public/index.html Visa fil

@@ -0,0 +1,17 @@
1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
+    <title></title>
9
+  </head>
10
+  <body>
11
+    <noscript>
12
+      <strong>We're sorry but iview-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
+    </noscript>
14
+    <div id="app"></div>
15
+    <!-- built files will be auto injected -->
16
+  </body>
17
+</html>

+ 14
- 13
src/App.vue Visa fil

@@ -1,26 +1,27 @@
1 1
 <template>
2 2
   <div id="app">
3
-    <!-- <router-view/> -->
4
-    <home/>
3
+    <router-view/>
5 4
   </div>
6 5
 </template>
7 6
 
8 7
 <script>
9
-import home from "./views/home"
10 8
 export default {
11
-  name: 'App',
12
-  components: {
13
-    "home":home
14
-  }
9
+  name: 'App'
15 10
 }
16 11
 </script>
17 12
 
18
-<style>
13
+<style lang="less">
14
+.size{
15
+  width: 100%;
16
+  height: 100%;
17
+}
18
+html,body{
19
+  .size;
20
+  overflow: hidden;
21
+  margin: 0;
22
+  padding: 0;
23
+}
19 24
 #app {
20
-  font-family: 'Avenir', Helvetica, Arial, sans-serif;
21
-  -webkit-font-smoothing: antialiased;
22
-  -moz-osx-font-smoothing: grayscale;
23
-  text-align: center;
24
-  color: #2c3e50;
25
+  .size;
25 26
 }
26 27
 </style>

+ 51
- 0
src/api/data.js Visa fil

@@ -0,0 +1,51 @@
1
+import axios from '@/libs/api.request'
2
+
3
+export const getTableData = () => {
4
+  return axios.request({
5
+    url: 'get_table_data',
6
+    method: 'get'
7
+  })
8
+}
9
+
10
+export const getDragList = () => {
11
+  return axios.request({
12
+    url: 'get_drag_list',
13
+    method: 'get'
14
+  })
15
+}
16
+
17
+export const errorReq = () => {
18
+  return axios.request({
19
+    url: 'error_url',
20
+    method: 'post'
21
+  })
22
+}
23
+
24
+export const saveErrorLogger = info => {
25
+  return axios.request({
26
+    url: 'save_error_logger',
27
+    data: info,
28
+    method: 'post'
29
+  })
30
+}
31
+
32
+export const uploadImg = formData => {
33
+  return axios.request({
34
+    url: 'image/upload',
35
+    data: formData
36
+  })
37
+}
38
+
39
+export const getOrgData = () => {
40
+  return axios.request({
41
+    url: 'get_org_data',
42
+    method: 'get'
43
+  })
44
+}
45
+
46
+export const getTreeSelectData = () => {
47
+  return axios.request({
48
+    url: 'get_tree_select_data',
49
+    method: 'get'
50
+  })
51
+}

+ 11
- 0
src/api/routers.js Visa fil

@@ -0,0 +1,11 @@
1
+import axios from '@/libs/api.request'
2
+
3
+export const getRouterReq = (access) => {
4
+  return axios.request({
5
+    url: 'get_router',
6
+    params: {
7
+      access
8
+    },
9
+    method: 'get'
10
+  })
11
+}

+ 84
- 0
src/api/user.js Visa fil

@@ -0,0 +1,84 @@
1
+import axios from '@/libs/api.request'
2
+
3
+export const login = ({ userName, password }) => {
4
+  const data = {
5
+    userName,
6
+    password
7
+  }
8
+  return axios.request({
9
+    url: 'login',
10
+    data,
11
+    method: 'post'
12
+  })
13
+}
14
+
15
+export const getUserInfo = (token) => {
16
+  return axios.request({
17
+    url: 'get_info',
18
+    params: {
19
+      token
20
+    },
21
+    method: 'get'
22
+  })
23
+}
24
+
25
+export const logout = (token) => {
26
+  return axios.request({
27
+    url: 'logout',
28
+    method: 'post'
29
+  })
30
+}
31
+
32
+export const getUnreadCount = () => {
33
+  return axios.request({
34
+    url: 'message/count',
35
+    method: 'get'
36
+  })
37
+}
38
+
39
+export const getMessage = () => {
40
+  return axios.request({
41
+    url: 'message/init',
42
+    method: 'get'
43
+  })
44
+}
45
+
46
+export const getContentByMsgId = msg_id => {
47
+  return axios.request({
48
+    url: 'message/content',
49
+    method: 'get',
50
+    params: {
51
+      msg_id
52
+    }
53
+  })
54
+}
55
+
56
+export const hasRead = msg_id => {
57
+  return axios.request({
58
+    url: 'message/has_read',
59
+    method: 'post',
60
+    data: {
61
+      msg_id
62
+    }
63
+  })
64
+}
65
+
66
+export const removeReaded = msg_id => {
67
+  return axios.request({
68
+    url: 'message/remove_readed',
69
+    method: 'post',
70
+    data: {
71
+      msg_id
72
+    }
73
+  })
74
+}
75
+
76
+export const restoreTrash = msg_id => {
77
+  return axios.request({
78
+    url: 'message/restore',
79
+    method: 'post',
80
+    data: {
81
+      msg_id
82
+    }
83
+  })
84
+}

+ 37
- 0
src/assets/icons/iconfont.css Visa fil

@@ -0,0 +1,37 @@
1
+
2
+@font-face {font-family: "iconfont";
3
+  src: url('iconfont.eot?t=1541579316141'); /* IE9*/
4
+  src: url('iconfont.eot?t=1541579316141#iefix') format('embedded-opentype'), /* IE6-IE8 */
5
+  url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAiEAAsAAAAADmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8eUnXY21hcAAAAYAAAACjAAACLi+YJuBnbHlmAAACJAAABAgAAAcg4dRWHmhlYWQAAAYsAAAAMQAAADYTL8piaGhlYQAABmAAAAAgAAAAJAfdA4xobXR4AAAGgAAAABQAAAAsLAD//2xvY2EAAAaUAAAAGAAAABgImgpGbWF4cAAABqwAAAAfAAAAIAEcAG5uYW1lAAAGzAAAAUUAAAJtPlT+fXBvc3QAAAgUAAAAbgAAAI54roygeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMTx/ytzwv4EhhrmBoRkozAiSAwDuUwzMeJzlkUEKwkAMRd/YabXFhQvxFF6qPYPrUujGY7jyIr1JoZNjtMnEhag3MOEN5MMk8D9QAoVyVSKEJwGrh6oh6wVN1iM3nc+cVImJVKdOehlklElmWdYVstp+ql8VdIv15a1NLW0zFXsO7Kjz3erH/3+rY37vr6kxnx1LKNWOJZlaxxJNnWOpSu+ot8jgqMvI6KjfyOSo88jsaAbI4tBsig89rQB4nLVUTWwbRRSeNzO767i2g7N/FP9s7MRrE5ON4/V6rSZyU0PiINSSNImES4IUoapWz6hEiqiMBDQqEojkAkiFStyKRC+9VSoFCeUEyqESVUAqEkcu3OAQb3hrJxAXwSGI3X0/szPz5vvm2x0i7O/vf8IJe5VkSJnUyUtklRBQJE1VIjRtUafkmk6pSu2ipleh4+xikkKxSksWTUeo8m8NoagpYtoslTmxrLl37z64e33esuJjU8P5Wd262LxoPVnPZ06Pxfe+C0YjkhSJygPhQCA8ABPOykwuN7NyuRvgUnAgLEnhATkaCQQiUe/7XKUyV6nQz+t2o7l66+rs7NVbq82GXTdrdjxjRGU5amTids2bUDMFtzCsqsMYMqr3IDY6OT05GjsI8Exv/6CSkOWEQigh+y3clxY5QVTcEZFIGtHLxDUJs6WsHR1y9SFKdr1HggCp3V1ICYL36OOpVmvKN9bC1u6R3vZ0qwWtVovgJfqOfUvfIYxIWL+fyETHNVJqSkIT1JTjW8ZWh3yDJDz0ctvsyt51etvrg9/QHhqGlzMM+vbmizPnDWPLMNbW19e7tffvsBzL99aWEfBRY46t+tbe3PypXv/IMDYN43WsQBe9HL2NC33RuxABrPsG+xH3o4bVRE2KgCRqulbWNf8W/UYVHM129aKra24VshZkq+CWD/Oy6Xt8cGYEthgHVlVliCfynAlqjo6oysTKlYUAD4docMI5/1ZioN+GwZNBcTwWUmTdBUqhTwX29QebXzF4An4JJMzwfMl+WQ01+IlQZVR4yhie53ycA16pOI/ODiYNGK4MChdCgXNnX5gIJXPCSYnf2OF850aQ+zJIyOs+u8+mMO8jQdwtg1TIWVRjKAnFcslMi8KfGUPoSUCergUyUk77dMyS69Ms6tijKZKYwUGKbpfdzu+iYeZYAHMFiOVi+MD7h9mb99qC0L7X8c+XatMfTj97KZ5IxJt/pd43tYYQKEjAnXMOB6kQEBrwg+LPjindAPOHNdC3q3ait0I3/ZIunZEARLNYNEUA6czSP3N/7j9wz6ZESdX0VNl1zGNS/szbQaQSIGk4DtVPcZf8AgXpf9A2OyTit5s2syZmand46bhEe2WtodLHkvaoqtTXuXN2/c42WADP9HGfbUcUW7JgqHss4xHtlMys679FqUomdP9VJBQBdnlPABBubpuNwqnmQj6/0HwNQzKxDUJFgKiXurBG6dqFjmeBzsvtRPJgGIZThYa5fdOvsReOticPh6JHHXxsv7ItJpOniYPYsmZ/x0QD/o5P105DeQwF6MH33ogoLi+KQp7zpY3HQV5bFMURzheXeds7gpP+jKNXljjHuYvXHke7cdCxLLZf6YX7B63UcCV4nGNgZGBgAOKAN2ZR8fw2Xxm4WRhA4AbHYRMY/f///1oWBuYGIJeDgQkkCgAvWgs2AAAAeJxjYGRgYG7438AQw8Lw/z8DAwsDA1AEBXADAHXiBHJ4nGNhYGBgYfj/nwVM48cATwECKwAAAAAAjAC6AOgBFAGAAf4CbgLqAzgDkHicY2BkYGDgZkhiYGcAASYg5gJCBob/YD4DABOmAYsAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYhdDoIwEAb3a6k/YIIX8VArWewmdJFWJOnpJTG+OQ+TzJCjLy39p4ODR4OAA4444YwWHS7U3IVzn6Voldtb8ksHnvohrlqjjmw1rmzXsvdT7fEbblnCmOfNfJIYStJJfGIL27yb6AOCGR89AAA=') format('woff'),
6
+  url('iconfont.ttf?t=1541579316141') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7
+  url('iconfont.svg?t=1541579316141#iconfont') format('svg'); /* iOS 4.1- */
8
+}
9
+
10
+.iconfont {
11
+  font-family:"iconfont" !important;
12
+  font-size:16px;
13
+  font-style:normal;
14
+  -webkit-font-smoothing: antialiased;
15
+  -moz-osx-font-smoothing: grayscale;
16
+}
17
+
18
+.icon-bear:before { content: "\e600"; }
19
+
20
+.icon-resize-vertical:before { content: "\e7c3"; }
21
+
22
+.icon-chuizhifanzhuan:before { content: "\e661"; }
23
+
24
+.icon-shuipingfanzhuan:before { content: "\e662"; }
25
+
26
+.icon-qq:before { content: "\e609"; }
27
+
28
+.icon-frown:before { content: "\e77e"; }
29
+
30
+.icon-meh:before { content: "\e780"; }
31
+
32
+.icon-smile:before { content: "\e783"; }
33
+
34
+.icon-man:before { content: "\e7e2"; }
35
+
36
+.icon-woman:before { content: "\e7e5"; }
37
+

Binär
src/assets/icons/iconfont.eot Visa fil


+ 56
- 0
src/assets/icons/iconfont.svg Visa fil

@@ -0,0 +1,56 @@
1
+<?xml version="1.0" standalone="no"?>
2
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+<!--
4
+2013-9-30: Created.
5
+-->
6
+<svg>
7
+<metadata>
8
+Created by iconfont
9
+</metadata>
10
+<defs>
11
+
12
+<font id="iconfont" horiz-adv-x="1024" >
13
+  <font-face
14
+    font-family="iconfont"
15
+    font-weight="500"
16
+    font-stretch="normal"
17
+    units-per-em="1024"
18
+    ascent="896"
19
+    descent="-128"
20
+  />
21
+    <missing-glyph />
22
+    
23
+    <glyph glyph-name="bear" unicode="&#58880;" d="M1024 683.008q0-70.656-46.08-121.856 46.08-89.088 46.08-193.536 0-96.256-39.936-181.248t-109.568-147.968-162.816-99.328-199.68-36.352-199.68 36.352-162.304 99.328-109.568 147.968-40.448 181.248q0 104.448 46.08 193.536-46.08 51.2-46.08 121.856 0 37.888 13.824 71.168t37.376 58.368 55.808 39.424 68.096 14.336q43.008 0 78.848-18.432t59.392-50.176q46.08 17.408 96.256 26.624t102.4 9.216 102.4-9.216 96.256-26.624q24.576 31.744 59.904 50.176t78.336 18.432q36.864 0 68.608-14.336t55.296-39.424 37.376-58.368 13.824-71.168zM205.824 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512-31.744000000000028q53.248 0 99.84 13.312t81.408 35.84 54.784 52.736 19.968 65.024q0 33.792-19.968 64t-54.784 52.736-81.408 35.84-99.84 13.312-99.84-13.312-81.408-35.84-54.784-52.736-19.968-64q0-34.816 19.968-65.024t54.784-52.736 81.408-35.84 99.84-13.312zM818.176 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512 235.51999999999998q39.936 0 68.096-9.728t28.16-24.064-28.16-24.064-68.096-9.728-68.096 9.728-28.16 24.064 28.16 24.064 68.096 9.728z"  horiz-adv-x="1024" />
24
+
25
+    
26
+    <glyph glyph-name="resize-vertical" unicode="&#59331;" d="M512 896C229.248 896 0 666.752 0 384s229.248-512 512-512 512 229.248 512 512S794.752 896 512 896zM576 192l64 0-128-128-128 128 64 0L448 576l-64 0 128 128 128-128-64 0L576 192z"  horiz-adv-x="1024" />
27
+
28
+    
29
+    <glyph glyph-name="chuizhifanzhuan" unicode="&#58977;" d="M286.01856 645.08416l472.4224 0 0-146.2784-472.4224 0 0 146.2784ZM87.19872 420.37248l885.80096 0 0-70.87104-885.80096 0 0 70.87104ZM773.55008 268.05248l0-31.0016L270.6688 237.05088l0 31.0016L773.55008 268.05248zM773.55008 121.4208l0-31.0016L270.6688 90.4192l0 31.0016L773.55008 121.4208zM742.54848 240.75776l31.0016 0 0-123.04896-31.0016 0L742.54848 240.75776zM270.70464 240.57856l31.0016 0 0-123.04896-31.0016 0L270.70464 240.57856z"  horiz-adv-x="1024" />
30
+
31
+    
32
+    <glyph glyph-name="shuipingfanzhuan" unicode="&#58978;" d="M252.76928 596.096l146.2784 0 0-472.42752-146.2784 0 0 472.42752ZM477.48096 810.65472l70.87104 0 0-885.80608-70.87104 0 0 885.80608ZM629.80096 611.2l31.0016 0 0-502.88128-31.0016 0L629.80096 611.2zM776.42752 611.2l31.0016 0 0-502.88128-31.0016 0L776.42752 611.2zM657.09056 580.1984l0 31.0016 123.04896 0 0-31.0016L657.09056 580.1984zM657.27488 108.35456l0 31.0016 123.04896 0 0-31.0016L657.27488 108.35456z"  horiz-adv-x="1024" />
33
+
34
+    
35
+    <glyph glyph-name="qq" unicode="&#58889;" d="M147.372058 491.394284c-5.28997-13.909921 2.431986-22.698872 0-75.732573-0.682996-14.25092-62.165649-78.762555-86.569511-145.791177-24.192863-66.517625-27.519845-135.978232 9.811944-163.285078 37.419789-27.305846 72.191593 90.879487 76.757567 73.685584 1.961989-7.509958 4.436975-15.317914 7.423958-23.338868a331.945126 331.945126 0 0 1 61.140655-101.162429c5.929967-6.783962-36.009797-19.199892-61.140655-61.99365-25.173858-42.751759 7.209959-120.49032 132.223254-120.49032 161.27909 0 197.288886 56.70368 200.574868 56.447681 12.031932-0.895995 12.841928 0 25.599855 0 15.572912 0 9.129948-1.279993 23.593867 0 7.807956 0.682996 86.186514-67.839617 194.686901-56.447681 184.873956 19.45589 156.586116 81.40754 142.079198 120.48932-15.103915 40.83277-68.692612 59.946662-66.303626 62.549647 44.28775 48.938724 51.285711 79.018554 66.346626 123.9463 6.143965 18.473896 49.066723-101.674426 82.089537-73.685584 13.781922 11.690934 41.301767 60.24566 13.781922 163.285078-27.519845 102.996419-80.767544 126.505286-79.615551 145.791177 2.389987 40.191773 1.023994 68.436614-1.023994 75.732573-9.812945 35.4128-30.378829 27.604844-30.378829 35.4128C858.450044 730.752933 705.10691 896 515.966978 896s-342.398067-165.289067-342.398068-369.192916c0-16.169909-14.378919-4.223976-26.154852-35.4128z"  horiz-adv-x="1024" />
36
+
37
+    
38
+    <glyph glyph-name="frown" unicode="&#59262;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM512 363c-85.5 0-155.6-67.3-160-151.6-0.2-4.6 3.4-8.4 8-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 259.9 461.5 299 512 299s92.1-39.1 95.8-88.6c0.3-4.2 3.9-7.4 8.1-7.4H664c4.6 0 8.2 3.8 8 8.4-4.4 84.3-74.5 151.6-160 151.6z"  horiz-adv-x="1024" />
39
+
40
+    
41
+    <glyph glyph-name="meh" unicode="&#59264;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 331H360c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h304c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8z"  horiz-adv-x="1024" />
42
+
43
+    
44
+    <glyph glyph-name="smile" unicode="&#59267;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 363h-48.1c-4.2 0-7.8-3.2-8.1-7.4C604 306.1 562.5 267 512 267s-92.1 39.1-95.8 88.6c-0.3 4.2-3.9 7.4-8.1 7.4H360c-4.6 0-8.2-3.8-8-8.4 4.4-84.3 74.5-151.6 160-151.6s155.6 67.3 160 151.6c0.2 4.6-3.4 8.4-8 8.4z"  horiz-adv-x="1024" />
45
+
46
+    
47
+    <glyph glyph-name="man" unicode="&#59362;" d="M874 776H622c-3.3 0-6-2.7-6-6v-56c0-3.3 2.7-6 6-6h160.4L583.1 508.7c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S120 356.9 120 280s30-149.3 84.4-203.6C258.7 22 331.1-8 408-8s149.3 30 203.6 84.4C666 130.7 696 203.1 696 280c0 64.1-20.8 124.9-59.2 174.9L836 654.1V494c0-3.3 2.7-6 6-6h56c3.3 0 6 2.7 6 6V746c0 16.5-13.5 30-30 30zM408 68c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z"  horiz-adv-x="1024" />
48
+
49
+    
50
+    <glyph glyph-name="woman" unicode="&#59365;" d="M909.7 739.4l-42.2 42.2c-3.1 3.1-8.2 3.1-11.3 0L764 689.4l-84.2 84.2c-3.1 3.1-8.2 3.1-11.3 0l-42.1-42.1c-3.1-3.1-3.1-8.1 0-11.3l84.2-84.2-135.5-135.3c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S112 348.9 112 272s30-149.3 84.4-203.6C250.7 14 323.1-16 400-16s149.3 30 203.6 84.4C658 122.7 688 195.1 688 272c0 64.2-20.9 125.1-59.3 175.1l135.4 135.4 84.2-84.2c3.1-3.1 8.2-3.1 11.3 0l42.1 42.1c3.1 3.1 3.1 8.1 0 11.3l-84.2 84.2 92.2 92.2c3.1 3.1 3.1 8.2 0 11.3zM400 60c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z"  horiz-adv-x="1024" />
51
+
52
+    
53
+
54
+
55
+  </font>
56
+</defs></svg>

Binär
src/assets/icons/iconfont.ttf Visa fil


Binär
src/assets/icons/iconfont.woff Visa fil


+ 1
- 0
src/assets/images/error-page/error-401.svg
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 1
- 0
src/assets/images/error-page/error-404.svg
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 1
- 0
src/assets/images/error-page/error-500.svg
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


Binär
src/assets/images/icon-qr-qq-wechat.png Visa fil


+ 1
- 0
src/assets/images/icon-social-bilibili.svg
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 1
- 0
src/assets/images/icon-social-juejin.svg Visa fil

@@ -0,0 +1 @@
1
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543883733" class="icon" style="" viewBox="0 0 1272 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16831" xmlns:xlink="http://www.w3.org/1999/xlink" width="496.875" height="400"><defs><style type="text/css"></style></defs><path d="M729.64116345 165.27693991L634.32650881 90.125l-99.5625 78.52693991-5.17887981 4.16056009 104.74137981 83.50215546 105.09051682-83.50215546-9.77586218-7.53556009z m361.21228445 291.47198236l-456.78879245 360.19396555-456.49784537-359.99030128L110.125 511.12715547l523.93965546 413.11745671 524.23060335-413.35021555-67.44181091-54.14547436z m-456.78879245 29.21120673L385.4784479 290.00646554 318.06573237 344.12284454l315.96982771 249.16810336 316.28987101-249.40086136-67.41271555-54.14547436-248.84806008 196.21551682z" fill="#006cff" p-id="16832"></path></svg>

+ 1
- 0
src/assets/images/icon-social-twitter.svg Visa fil

@@ -0,0 +1 @@
1
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543874130" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16498" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><defs><style type="text/css"></style></defs><path d="M511.8 0.6C229.2 0.6 0.1 229.7 0.1 512.3S229.2 1024 511.8 1024s511.7-229.1 511.7-511.7S794.4 0.6 511.8 0.6z m264.9 375.3c-0.1 0.1-0.1 0.2-0.2 0.3h0.2c-9 14.3-21.2 28.8-34.2 39.2-5.2 4.2-10.5 8.3-15.7 12.5v0.5c0.3 22.9-0.3 44.9-4.7 64.2-25.2 113.1-91.9 189.9-197.4 222.8-37.9 11.8-99.1 16.7-142.6 5.9-21.5-5.4-41-11.4-59.3-19.3-10.2-4.5-19.6-9.3-28.5-14.7l-8.8-5.3h0.5l-0.5-0.3c9.8 0.2 21.3 2.9 32.2 1.2 9.8-1.6 19.6-1.2 28.7-3.2 22.7-5 43-11.6 60.4-21.8 8.3-4.8 20.9-10.6 27-17.6-11.2 0.2-21.4-2.4-29.7-5.4-32.6-11.5-51.6-32.7-63.9-64.4h0.1c0-0.1-0.1-0.2-0.1-0.3 9.7 1.1 37.3 3.5 44.6-1.7-12.3-0.8-24.1-7.9-32.5-13.2-26.2-16.4-47.6-43.9-47.4-86.2v-0.3c3.5 1.7 6.9 3.3 10.4 4.9 6.6 2.8 13.3 4.3 21.1 5.9 3.1 0.7 9.3 2.4 13.2 1.4-5.1-5.8-13.2-9.7-18.4-16-14.7-18.3-28.7-45.3-25.2-77.4 0.5-4.7 1.3-9.4 2.6-14.3 2.5-9.7 6.5-18.3 10.8-26.2 0.2 0.1 0.4 0.2 0.5 0.3 2 4.2 6.4 7.2 9.1 10.6 8.6 10.7 19.2 20.3 30 28.7 36.7 28.7 69.9 46.4 123.1 59.5 13.5 3.3 29 5.9 45.1 5.9-1.9-5.8-2.7-13-2.7-20.5 0-9.7 1.3-19.6 3.3-26.8 9-32.1 28.5-55.2 57-67.6 6.9-3 14.4-5.2 22.4-6.9 4.1-0.6 8.2-1.1 12.3-1.6 39-0.7 59.8 13.5 79.6 31.6 16.8-1.4 38.7-10.8 51.6-17.4l12.6-6.9c0 0.1-0.1 0.3-0.1 0.4l0.1-0.1c-7.3 19.9-17.4 35.5-32.7 47.3-3.1 2.4-6.3 5.6-10 7.4 21.5-0.4 39.3-10 56.1-15.4v0.3z" fill="#2EB1EB" p-id="16499"></path><path d="M719.7 391.1s0.1 0 0.1-0.1c0 0-0.1 0-0.1 0.1zM726.8 428.4v-0.5 0.5zM336.4 479.9c3.3 0.7 9.9 2.7 13.8 1.2h-0.5l-0.1-0.1c-3.9 1-10.1-0.7-13.2-1.4-7.8-1.6-14.5-3.1-21.1-5.9-3.5-1.6-6.9-3.2-10.4-4.9v0.3c3.4 1.6 6.9 3.2 10.4 4.9 6.6 2.8 13.3 4.3 21.1 5.9zM719.6 391.4v0.2c21.9-0.2 39.8-10.1 56.9-15.4 0.1-0.1 0.1-0.2 0.2-0.3v-0.3c-16.9 5.3-34.6 14.9-56.1 15.4-0.4 0.1-0.7 0.3-1 0.4zM584.8 337.5c6.9-3 14.4-5.1 22.4-6.9 4.1-0.6 8.2-1 12.3-1.6 39-0.7 59.8 13.5 79.6 31.6 16.8-1.4 38.7-10.8 51.6-17.4 4.2-2.3 8.3-4.5 12.5-6.8 0-0.1 0.1-0.3 0.1-0.4l-12.6 6.9c-12.9 6.6-34.8 16-51.6 17.4-19.8-18.1-40.6-32.3-79.6-31.6-4.1 0.5-8.2 1-12.3 1.6-8 1.7-15.5 3.9-22.4 6.9-28.5 12.4-48 35.5-57 67.6-2 7.2-3.4 17.2-3.3 26.8 0-9.6 1.3-19.4 3.3-26.5 9-32.1 28.5-55.2 57-67.6zM385.2 568.5h-0.4c-7.3 5.2-34.9 2.8-44.6 1.7 0 0.1 0.1 0.2 0.1 0.3 10 1.1 38.2 3.6 44.9-2zM319.4 347.4c0.1 0.1 0.3 0.1 0.5 0.3 2 4.1 6.3 7.1 9.1 10.6 8.6 10.6 19.2 20.2 30 28.7 36.8 28.7 69.9 46.4 123.1 59.5 13.5 3.3 29.1 5.9 45.2 5.9 0-0.1-0.1-0.2-0.1-0.3-16.1 0-31.6-2.6-45.1-5.9-53.2-13.1-86.4-30.8-123.1-59.5-10.8-8.4-21.4-18-30-28.7-2.7-3.4-7.1-6.4-9.1-10.6-0.1-0.1-0.3-0.2-0.5-0.3-4.3 7.9-8.3 16.5-10.8 26.2-1.3 4.9-2.1 9.6-2.6 14.3 0.5-4.6 1.3-9.2 2.6-14 2.5-9.7 6.5-18.3 10.8-26.2zM317.7 683.2c9.9-1.6 19.6-1.2 28.7-3.2 22.8-5 43-11.6 60.4-21.8 8.4-4.9 21.3-10.8 27.3-17.9h-0.3c-6.1 7-18.7 12.8-27 17.6-17.4 10.2-37.7 16.8-60.4 21.8-9.1 2-18.9 1.6-28.7 3.2-10.9 1.7-22.4-1-32.2-1.2l0.5 0.3c9.7 0.4 21 2.9 31.7 1.2z" fill="#FFFFFF" p-id="16500"></path></svg>

+ 1
- 0
src/assets/images/icon-social-zhihu.svg Visa fil

@@ -0,0 +1 @@
1
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547543863835" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16165" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><defs><style type="text/css"></style></defs><path d="M512 1024C229.236364 1024 0 794.763636 0 512S229.236364 0 512 0s512 229.236364 512 512-229.236364 512-512 512z m-129.861818-756.48s-36.212364 2.094545-48.989091 24.482909c-12.8 22.365091-54.318545 137.378909-54.318546 137.378909s13.847273 6.376727 37.28291-10.658909c23.435636-17.035636 30.882909-46.848 30.882909-46.848l42.589091-2.117818 1.070545 121.390545s-73.495273-1.070545-88.413091 0c-14.894545 1.047273-23.412364 40.448-23.412364 40.448h111.825455s-9.588364 67.095273-38.353455 116.084364c-28.741818 48.989091-83.060364 87.319273-83.060363 87.319273s39.424 15.965091 77.730909-6.4c38.353455-22.341818 66.629818-120.692364 66.629818-120.692364l89.925818 110.056727s8.192-52.386909-1.466182-67.188363c-9.658182-14.778182-62.208-74.286545-62.208-74.286546l-22.946909 20.247273 16.337455-65.117091h97.954909s0-38.353455-19.153455-40.494545c-19.176727-2.094545-78.801455 0-78.801454 0V371.898182h88.389818s-1.070545-39.400727-18.106182-39.400727h-143.755636l22.341818-64.954182z m169.984 61.184v358.562909h36.002909l13.102545 45.009455 63.348364-45.009455h89.064727V328.704h-201.518545z" fill="#0f84fd" p-id="16166"></path><path d="M594.781091 368.64h117.899636v277.876364h-41.890909l-53.364363 40.261818-11.636364-40.261818h-11.008V368.64z" fill="#0f84fd" p-id="16167"></path></svg>

Binär
src/assets/images/login-bg.jpg Visa fil


Binär
src/assets/images/logo-min.jpg Visa fil


Binär
src/assets/images/logo.jpg Visa fil


Binär
src/assets/images/talkingdata.png Visa fil


Binär
src/assets/logo copy.png Visa fil


+ 58
- 0
src/components/charts/bar.vue Visa fil

@@ -0,0 +1,58 @@
1
+<template>
2
+  <div ref="dom" class="charts chart-bar"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+import tdTheme from './theme.json'
8
+import { on, off } from '@/libs/tools'
9
+echarts.registerTheme('tdTheme', tdTheme)
10
+export default {
11
+  name: 'ChartBar',
12
+  props: {
13
+    value: Object,
14
+    text: String,
15
+    subtext: String
16
+  },
17
+  data () {
18
+    return {
19
+      dom: null
20
+    }
21
+  },
22
+  methods: {
23
+    resize () {
24
+      this.dom.resize()
25
+    }
26
+  },
27
+  mounted () {
28
+    this.$nextTick(() => {
29
+      let xAxisData = Object.keys(this.value)
30
+      let seriesData = Object.values(this.value)
31
+      let option = {
32
+        title: {
33
+          text: this.text,
34
+          subtext: this.subtext,
35
+          x: 'center'
36
+        },
37
+        xAxis: {
38
+          type: 'category',
39
+          data: xAxisData
40
+        },
41
+        yAxis: {
42
+          type: 'value'
43
+        },
44
+        series: [{
45
+          data: seriesData,
46
+          type: 'bar'
47
+        }]
48
+      }
49
+      this.dom = echarts.init(this.$refs.dom, 'tdTheme')
50
+      this.dom.setOption(option)
51
+      on(window, 'resize', this.resize)
52
+    })
53
+  },
54
+  beforeDestroy () {
55
+    off(window, 'resize', this.resize)
56
+  }
57
+}
58
+</script>

+ 3
- 0
src/components/charts/index.js Visa fil

@@ -0,0 +1,3 @@
1
+import ChartPie from './pie.vue'
2
+import ChartBar from './bar.vue'
3
+export { ChartPie, ChartBar }

+ 70
- 0
src/components/charts/pie.vue Visa fil

@@ -0,0 +1,70 @@
1
+<template>
2
+  <div ref="dom" class="charts chart-pie"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+import tdTheme from './theme.json'
8
+import { on, off } from '@/libs/tools'
9
+echarts.registerTheme('tdTheme', tdTheme)
10
+export default {
11
+  name: 'ChartPie',
12
+  props: {
13
+    value: Array,
14
+    text: String,
15
+    subtext: String
16
+  },
17
+  data () {
18
+    return {
19
+      dom: null
20
+    }
21
+  },
22
+  methods: {
23
+    resize () {
24
+      this.dom.resize()
25
+    }
26
+  },
27
+  mounted () {
28
+    this.$nextTick(() => {
29
+      let legend = this.value.map(_ => _.name)
30
+      let option = {
31
+        title: {
32
+          text: this.text,
33
+          subtext: this.subtext,
34
+          x: 'center'
35
+        },
36
+        tooltip: {
37
+          trigger: 'item',
38
+          formatter: '{a} <br/>{b} : {c} ({d}%)'
39
+        },
40
+        legend: {
41
+          orient: 'vertical',
42
+          left: 'left',
43
+          data: legend
44
+        },
45
+        series: [
46
+          {
47
+            type: 'pie',
48
+            radius: '55%',
49
+            center: ['50%', '60%'],
50
+            data: this.value,
51
+            itemStyle: {
52
+              emphasis: {
53
+                shadowBlur: 10,
54
+                shadowOffsetX: 0,
55
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
56
+              }
57
+            }
58
+          }
59
+        ]
60
+      }
61
+      this.dom = echarts.init(this.$refs.dom, 'tdTheme')
62
+      this.dom.setOption(option)
63
+      on(window, 'resize', this.resize)
64
+    })
65
+  },
66
+  beforeDestroy () {
67
+    off(window, 'resize', this.resize)
68
+  }
69
+}
70
+</script>

+ 491
- 0
src/components/charts/theme.json Visa fil

@@ -0,0 +1,491 @@
1
+
2
+{
3
+    "color": [
4
+        "#2d8cf0",
5
+        "#19be6b",
6
+        "#ff9900",
7
+        "#E46CBB",
8
+        "#9A66E4",
9
+        "#ed3f14"
10
+    ],
11
+    "backgroundColor": "rgba(0,0,0,0)",
12
+    "textStyle": {},
13
+    "title": {
14
+        "textStyle": {
15
+            "color": "#516b91"
16
+        },
17
+        "subtextStyle": {
18
+            "color": "#93b7e3"
19
+        }
20
+    },
21
+    "line": {
22
+        "itemStyle": {
23
+            "normal": {
24
+                "borderWidth": "2"
25
+            }
26
+        },
27
+        "lineStyle": {
28
+            "normal": {
29
+                "width": "2"
30
+            }
31
+        },
32
+        "symbolSize": "6",
33
+        "symbol": "emptyCircle",
34
+        "smooth": true
35
+    },
36
+    "radar": {
37
+        "itemStyle": {
38
+            "normal": {
39
+                "borderWidth": "2"
40
+            }
41
+        },
42
+        "lineStyle": {
43
+            "normal": {
44
+                "width": "2"
45
+            }
46
+        },
47
+        "symbolSize": "6",
48
+        "symbol": "emptyCircle",
49
+        "smooth": true
50
+    },
51
+    "bar": {
52
+        "itemStyle": {
53
+            "normal": {
54
+                "barBorderWidth": 0,
55
+                "barBorderColor": "#ccc"
56
+            },
57
+            "emphasis": {
58
+                "barBorderWidth": 0,
59
+                "barBorderColor": "#ccc"
60
+            }
61
+        }
62
+    },
63
+    "pie": {
64
+        "itemStyle": {
65
+            "normal": {
66
+                "borderWidth": 0,
67
+                "borderColor": "#ccc"
68
+            },
69
+            "emphasis": {
70
+                "borderWidth": 0,
71
+                "borderColor": "#ccc"
72
+            }
73
+        }
74
+    },
75
+    "scatter": {
76
+        "itemStyle": {
77
+            "normal": {
78
+                "borderWidth": 0,
79
+                "borderColor": "#ccc"
80
+            },
81
+            "emphasis": {
82
+                "borderWidth": 0,
83
+                "borderColor": "#ccc"
84
+            }
85
+        }
86
+    },
87
+    "boxplot": {
88
+        "itemStyle": {
89
+            "normal": {
90
+                "borderWidth": 0,
91
+                "borderColor": "#ccc"
92
+            },
93
+            "emphasis": {
94
+                "borderWidth": 0,
95
+                "borderColor": "#ccc"
96
+            }
97
+        }
98
+    },
99
+    "parallel": {
100
+        "itemStyle": {
101
+            "normal": {
102
+                "borderWidth": 0,
103
+                "borderColor": "#ccc"
104
+            },
105
+            "emphasis": {
106
+                "borderWidth": 0,
107
+                "borderColor": "#ccc"
108
+            }
109
+        }
110
+    },
111
+    "sankey": {
112
+        "itemStyle": {
113
+            "normal": {
114
+                "borderWidth": 0,
115
+                "borderColor": "#ccc"
116
+            },
117
+            "emphasis": {
118
+                "borderWidth": 0,
119
+                "borderColor": "#ccc"
120
+            }
121
+        }
122
+    },
123
+    "funnel": {
124
+        "itemStyle": {
125
+            "normal": {
126
+                "borderWidth": 0,
127
+                "borderColor": "#ccc"
128
+            },
129
+            "emphasis": {
130
+                "borderWidth": 0,
131
+                "borderColor": "#ccc"
132
+            }
133
+        }
134
+    },
135
+    "gauge": {
136
+        "itemStyle": {
137
+            "normal": {
138
+                "borderWidth": 0,
139
+                "borderColor": "#ccc"
140
+            },
141
+            "emphasis": {
142
+                "borderWidth": 0,
143
+                "borderColor": "#ccc"
144
+            }
145
+        }
146
+    },
147
+    "candlestick": {
148
+        "itemStyle": {
149
+            "normal": {
150
+                "color": "#edafda",
151
+                "color0": "transparent",
152
+                "borderColor": "#d680bc",
153
+                "borderColor0": "#8fd3e8",
154
+                "borderWidth": "2"
155
+            }
156
+        }
157
+    },
158
+    "graph": {
159
+        "itemStyle": {
160
+            "normal": {
161
+                "borderWidth": 0,
162
+                "borderColor": "#ccc"
163
+            }
164
+        },
165
+        "lineStyle": {
166
+            "normal": {
167
+                "width": 1,
168
+                "color": "#aaa"
169
+            }
170
+        },
171
+        "symbolSize": "6",
172
+        "symbol": "emptyCircle",
173
+        "smooth": true,
174
+        "color": [
175
+            "#2d8cf0",
176
+            "#19be6b",
177
+            "#f5ae4a",
178
+            "#9189d5",
179
+            "#56cae2",
180
+            "#cbb0e3"
181
+        ],
182
+        "label": {
183
+            "normal": {
184
+                "textStyle": {
185
+                    "color": "#eee"
186
+                }
187
+            }
188
+        }
189
+    },
190
+    "map": {
191
+        "itemStyle": {
192
+            "normal": {
193
+                "areaColor": "#f3f3f3",
194
+                "borderColor": "#516b91",
195
+                "borderWidth": 0.5
196
+            },
197
+            "emphasis": {
198
+                "areaColor": "rgba(165,231,240,1)",
199
+                "borderColor": "#516b91",
200
+                "borderWidth": 1
201
+            }
202
+        },
203
+        "label": {
204
+            "normal": {
205
+                "textStyle": {
206
+                    "color": "#000"
207
+                }
208
+            },
209
+            "emphasis": {
210
+                "textStyle": {
211
+                    "color": "rgb(81,107,145)"
212
+                }
213
+            }
214
+        }
215
+    },
216
+    "geo": {
217
+        "itemStyle": {
218
+            "normal": {
219
+                "areaColor": "#f3f3f3",
220
+                "borderColor": "#516b91",
221
+                "borderWidth": 0.5
222
+            },
223
+            "emphasis": {
224
+                "areaColor": "rgba(165,231,240,1)",
225
+                "borderColor": "#516b91",
226
+                "borderWidth": 1
227
+            }
228
+        },
229
+        "label": {
230
+            "normal": {
231
+                "textStyle": {
232
+                    "color": "#000"
233
+                }
234
+            },
235
+            "emphasis": {
236
+                "textStyle": {
237
+                    "color": "rgb(81,107,145)"
238
+                }
239
+            }
240
+        }
241
+    },
242
+    "categoryAxis": {
243
+        "axisLine": {
244
+            "show": true,
245
+            "lineStyle": {
246
+                "color": "#cccccc"
247
+            }
248
+        },
249
+        "axisTick": {
250
+            "show": false,
251
+            "lineStyle": {
252
+                "color": "#333"
253
+            }
254
+        },
255
+        "axisLabel": {
256
+            "show": true,
257
+            "textStyle": {
258
+                "color": "#999999"
259
+            }
260
+        },
261
+        "splitLine": {
262
+            "show": true,
263
+            "lineStyle": {
264
+                "color": [
265
+                    "#eeeeee"
266
+                ]
267
+            }
268
+        },
269
+        "splitArea": {
270
+            "show": false,
271
+            "areaStyle": {
272
+                "color": [
273
+                    "rgba(250,250,250,0.05)",
274
+                    "rgba(200,200,200,0.02)"
275
+                ]
276
+            }
277
+        }
278
+    },
279
+    "valueAxis": {
280
+        "axisLine": {
281
+            "show": true,
282
+            "lineStyle": {
283
+                "color": "#cccccc"
284
+            }
285
+        },
286
+        "axisTick": {
287
+            "show": false,
288
+            "lineStyle": {
289
+                "color": "#333"
290
+            }
291
+        },
292
+        "axisLabel": {
293
+            "show": true,
294
+            "textStyle": {
295
+                "color": "#999999"
296
+            }
297
+        },
298
+        "splitLine": {
299
+            "show": true,
300
+            "lineStyle": {
301
+                "color": [
302
+                    "#eeeeee"
303
+                ]
304
+            }
305
+        },
306
+        "splitArea": {
307
+            "show": false,
308
+            "areaStyle": {
309
+                "color": [
310
+                    "rgba(250,250,250,0.05)",
311
+                    "rgba(200,200,200,0.02)"
312
+                ]
313
+            }
314
+        }
315
+    },
316
+    "logAxis": {
317
+        "axisLine": {
318
+            "show": true,
319
+            "lineStyle": {
320
+                "color": "#cccccc"
321
+            }
322
+        },
323
+        "axisTick": {
324
+            "show": false,
325
+            "lineStyle": {
326
+                "color": "#333"
327
+            }
328
+        },
329
+        "axisLabel": {
330
+            "show": true,
331
+            "textStyle": {
332
+                "color": "#999999"
333
+            }
334
+        },
335
+        "splitLine": {
336
+            "show": true,
337
+            "lineStyle": {
338
+                "color": [
339
+                    "#eeeeee"
340
+                ]
341
+            }
342
+        },
343
+        "splitArea": {
344
+            "show": false,
345
+            "areaStyle": {
346
+                "color": [
347
+                    "rgba(250,250,250,0.05)",
348
+                    "rgba(200,200,200,0.02)"
349
+                ]
350
+            }
351
+        }
352
+    },
353
+    "timeAxis": {
354
+        "axisLine": {
355
+            "show": true,
356
+            "lineStyle": {
357
+                "color": "#cccccc"
358
+            }
359
+        },
360
+        "axisTick": {
361
+            "show": false,
362
+            "lineStyle": {
363
+                "color": "#333"
364
+            }
365
+        },
366
+        "axisLabel": {
367
+            "show": true,
368
+            "textStyle": {
369
+                "color": "#999999"
370
+            }
371
+        },
372
+        "splitLine": {
373
+            "show": true,
374
+            "lineStyle": {
375
+                "color": [
376
+                    "#eeeeee"
377
+                ]
378
+            }
379
+        },
380
+        "splitArea": {
381
+            "show": false,
382
+            "areaStyle": {
383
+                "color": [
384
+                    "rgba(250,250,250,0.05)",
385
+                    "rgba(200,200,200,0.02)"
386
+                ]
387
+            }
388
+        }
389
+    },
390
+    "toolbox": {
391
+        "iconStyle": {
392
+            "normal": {
393
+                "borderColor": "#999"
394
+            },
395
+            "emphasis": {
396
+                "borderColor": "#666"
397
+            }
398
+        }
399
+    },
400
+    "legend": {
401
+        "textStyle": {
402
+            "color": "#999999"
403
+        }
404
+    },
405
+    "tooltip": {
406
+        "axisPointer": {
407
+            "lineStyle": {
408
+                "color": "#ccc",
409
+                "width": 1
410
+            },
411
+            "crossStyle": {
412
+                "color": "#ccc",
413
+                "width": 1
414
+            }
415
+        }
416
+    },
417
+    "timeline": {
418
+        "lineStyle": {
419
+            "color": "#8fd3e8",
420
+            "width": 1
421
+        },
422
+        "itemStyle": {
423
+            "normal": {
424
+                "color": "#8fd3e8",
425
+                "borderWidth": 1
426
+            },
427
+            "emphasis": {
428
+                "color": "#8fd3e8"
429
+            }
430
+        },
431
+        "controlStyle": {
432
+            "normal": {
433
+                "color": "#8fd3e8",
434
+                "borderColor": "#8fd3e8",
435
+                "borderWidth": 0.5
436
+            },
437
+            "emphasis": {
438
+                "color": "#8fd3e8",
439
+                "borderColor": "#8fd3e8",
440
+                "borderWidth": 0.5
441
+            }
442
+        },
443
+        "checkpointStyle": {
444
+            "color": "#8fd3e8",
445
+            "borderColor": "rgba(138,124,168,0.37)"
446
+        },
447
+        "label": {
448
+            "normal": {
449
+                "textStyle": {
450
+                    "color": "#8fd3e8"
451
+                }
452
+            },
453
+            "emphasis": {
454
+                "textStyle": {
455
+                    "color": "#8fd3e8"
456
+                }
457
+            }
458
+        }
459
+    },
460
+    "visualMap": {
461
+        "color": [
462
+            "#516b91",
463
+            "#59c4e6",
464
+            "#a5e7f0"
465
+        ]
466
+    },
467
+    "dataZoom": {
468
+        "backgroundColor": "rgba(0,0,0,0)",
469
+        "dataBackgroundColor": "rgba(255,255,255,0.3)",
470
+        "fillerColor": "rgba(167,183,204,0.4)",
471
+        "handleColor": "#a7b7cc",
472
+        "handleSize": "100%",
473
+        "textStyle": {
474
+            "color": "#333"
475
+        }
476
+    },
477
+    "markPoint": {
478
+        "label": {
479
+            "normal": {
480
+                "textStyle": {
481
+                    "color": "#eee"
482
+                }
483
+            },
484
+            "emphasis": {
485
+                "textStyle": {
486
+                    "color": "#eee"
487
+                }
488
+            }
489
+        }
490
+    }
491
+}

+ 42
- 0
src/components/common-icon/common-icon.vue Visa fil

@@ -0,0 +1,42 @@
1
+<template>
2
+  <component :is="iconType" :type="iconName" :color="iconColor" :size="iconSize"/>
3
+</template>
4
+
5
+<script>
6
+import Icons from '_c/icons'
7
+export default {
8
+  name: 'CommonIcon',
9
+  components: { Icons },
10
+  props: {
11
+    type: {
12
+      type: String,
13
+      required: true
14
+    },
15
+    color: String,
16
+    size: Number
17
+  },
18
+  computed: {
19
+    iconType () {
20
+      return this.type.indexOf('_') === 0 ? 'Icons' : 'Icon'
21
+    },
22
+    iconName () {
23
+      return this.iconType === 'Icons' ? this.getCustomIconName(this.type) : this.type
24
+    },
25
+    iconSize () {
26
+      return this.size || (this.iconType === 'Icons' ? 12 : undefined)
27
+    },
28
+    iconColor () {
29
+      return this.color || ''
30
+    }
31
+  },
32
+  methods: {
33
+    getCustomIconName (iconName) {
34
+      return iconName.slice(1)
35
+    }
36
+  }
37
+}
38
+</script>
39
+
40
+<style>
41
+
42
+</style>

+ 2
- 0
src/components/common-icon/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import CommonIcon from './common-icon.vue'
2
+export default CommonIcon

+ 8
- 0
src/components/common/common.less Visa fil

@@ -0,0 +1,8 @@
1
+.no-select{
2
+  -webkit-touch-callout: none;
3
+  -webkit-user-select: none;
4
+  -khtml-user-select: none;
5
+  -moz-user-select: none;
6
+  -ms-user-select: none;
7
+  user-select: none;
8
+}

+ 3
- 0
src/components/common/util.js Visa fil

@@ -0,0 +1,3 @@
1
+export const showTitle = (item, vm) => {
2
+  return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name)
3
+}

+ 174
- 0
src/components/count-to/count-to.vue Visa fil

@@ -0,0 +1,174 @@
1
+<template>
2
+  <div class="count-to-wrapper">
3
+    <slot name="left"/>
4
+    <p class="content-outer"><span :class="['count-to-count-text', countClass]" :id="counterId">{{ init }}</span><i :class="['count-to-unit-text', unitClass]">{{ unitText }}</i></p>
5
+    <slot name="right"/>
6
+  </div>
7
+</template>
8
+
9
+<script>
10
+import CountUp from 'countup'
11
+import './index.less'
12
+export default {
13
+  name: 'CountTo',
14
+  props: {
15
+    init: {
16
+      type: Number,
17
+      default: 0
18
+    },
19
+    /**
20
+     * @description 起始值,即动画开始前显示的数值
21
+     */
22
+    startVal: {
23
+      type: Number,
24
+      default: 0
25
+    },
26
+    /**
27
+     * @description 结束值,即动画结束后显示的数值
28
+     */
29
+    end: {
30
+      type: Number,
31
+      required: true
32
+    },
33
+    /**
34
+     * @description 保留几位小数
35
+     */
36
+    decimals: {
37
+      type: Number,
38
+      default: 0
39
+    },
40
+    /**
41
+     * @description 分隔整数和小数的符号,默认是小数点
42
+     */
43
+    decimal: {
44
+      type: String,
45
+      default: '.'
46
+    },
47
+    /**
48
+     * @description 动画持续的时间,单位是秒
49
+     */
50
+    duration: {
51
+      type: Number,
52
+      default: 2
53
+    },
54
+    /**
55
+     * @description 动画延迟开始的时间,单位是秒
56
+     */
57
+    delay: {
58
+      type: Number,
59
+      default: 0
60
+    },
61
+    /**
62
+     * @description 是否禁用easing动画效果
63
+     */
64
+    uneasing: {
65
+      type: Boolean,
66
+      default: false
67
+    },
68
+    /**
69
+     * @description 是否使用分组,分组后每三位会用一个符号分隔
70
+     */
71
+    usegroup: {
72
+      type: Boolean,
73
+      default: false
74
+    },
75
+    /**
76
+     * @description 用于分组(usegroup)的符号
77
+     */
78
+    separator: {
79
+      type: String,
80
+      default: ','
81
+    },
82
+    /**
83
+     * @description 是否简化显示,设为true后会使用unit单位来做相关省略
84
+     */
85
+    simplify: {
86
+      type: Boolean,
87
+      default: false
88
+    },
89
+    /**
90
+     * @description 自定义单位,如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
91
+     *              1000即显示为1K+
92
+     */
93
+    unit: {
94
+      type: Array,
95
+      default () {
96
+        return [[3, 'K+'], [6, 'M+'], [9, 'B+']]
97
+      }
98
+    },
99
+    countClass: {
100
+      type: String,
101
+      default: ''
102
+    },
103
+    unitClass: {
104
+      type: String,
105
+      default: ''
106
+    }
107
+  },
108
+  data () {
109
+    return {
110
+      counter: null,
111
+      unitText: ''
112
+    }
113
+  },
114
+  computed: {
115
+    counterId () {
116
+      return `count_to_${this._uid}`
117
+    }
118
+  },
119
+  methods: {
120
+    getHandleVal (val, len) {
121
+      return {
122
+        endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
123
+        unitText: this.unit[len - 1][1]
124
+      }
125
+    },
126
+    transformValue (val) {
127
+      let len = this.unit.length
128
+      let res = {
129
+        endVal: 0,
130
+        unitText: ''
131
+      }
132
+      if (val < Math.pow(10, this.unit[0][0])) res.endVal = val
133
+      else {
134
+        for (let i = 1; i < len; i++) {
135
+          if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0])) res = this.getHandleVal(val, i)
136
+        }
137
+      }
138
+      if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len)
139
+      return res
140
+    },
141
+    getValue (val) {
142
+      let res = 0
143
+      if (this.simplify) {
144
+        let { endVal, unitText } = this.transformValue(val)
145
+        this.unitText = unitText
146
+        res = endVal
147
+      } else {
148
+        res = val
149
+      }
150
+      return res
151
+    }
152
+  },
153
+  mounted () {
154
+    this.$nextTick(() => {
155
+      let endVal = this.getValue(this.end)
156
+      this.counter = new CountUp(this.counterId, this.startVal, endVal, this.decimals, this.duration, {
157
+        useEasing: !this.uneasing,
158
+        useGrouping: this.useGroup,
159
+        separator: this.separator,
160
+        decimal: this.decimal
161
+      })
162
+      setTimeout(() => {
163
+        if (!this.counter.error) this.counter.start()
164
+      }, this.delay)
165
+    })
166
+  },
167
+  watch: {
168
+    end (newVal) {
169
+      let endVal = this.getValue(newVal)
170
+      this.counter.update(endVal)
171
+    }
172
+  }
173
+}
174
+</script>

+ 2
- 0
src/components/count-to/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import countTo from './count-to.vue'
2
+export default countTo

+ 10
- 0
src/components/count-to/index.less Visa fil

@@ -0,0 +1,10 @@
1
+@prefix: ~"count-to";
2
+
3
+.@{prefix}-wrapper{
4
+  .content-outer{
5
+    display: inline-block;
6
+    .@{prefix}-unit-text{
7
+      font-style: normal;
8
+    }
9
+  }
10
+}

+ 2
- 0
src/components/cropper/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import Cropper from './index.vue'
2
+export default Cropper

+ 35
- 0
src/components/cropper/index.less Visa fil

@@ -0,0 +1,35 @@
1
+.bg{
2
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
3
+}
4
+.cropper-wrapper{
5
+  width: 600px;
6
+  height: 340px;
7
+  .img-box{
8
+    height: 340px;
9
+    width: 430px;
10
+    border: 1px solid #ebebeb;
11
+    display: inline-block;
12
+    .bg;
13
+    img{
14
+      max-width: 100%;
15
+      display: block;
16
+    }
17
+  }
18
+  .right-con{
19
+    display: inline-block;
20
+    width: 170px;
21
+    vertical-align: top;
22
+    box-sizing: border-box;
23
+    padding: 0 10px;
24
+    .preview-box{
25
+      height: 150px !important;
26
+      width: 100% !important;
27
+      overflow: hidden;
28
+      border: 1px solid #ebebeb;
29
+      .bg;
30
+    }
31
+    .button-box{
32
+      padding: 10px 0 0;
33
+    }
34
+  }
35
+}

+ 139
- 0
src/components/cropper/index.vue Visa fil

@@ -0,0 +1,139 @@
1
+<template>
2
+  <div class="cropper-wrapper">
3
+    <div class="img-box">
4
+      <img class="cropper-image" :id="imgId" alt="">
5
+    </div>
6
+    <div class="right-con">
7
+      <div v-if="preview" class="preview-box" :id="previewId"></div>
8
+      <div class="button-box">
9
+        <slot>
10
+          <Upload action="image/upload" :before-upload="beforeUpload">
11
+            <Button style="width: 150px;" type="primary">上传图片</Button>
12
+          </Upload>
13
+        </slot>
14
+        <div v-show="insideSrc">
15
+          <Button type="primary" @click="rotate">
16
+            <Icon type="md-refresh" :size="18"/>
17
+          </Button>
18
+          <Button type="primary" @click="shrink">
19
+            <Icon type="md-remove" :size="18"/>
20
+          </Button>
21
+          <Button type="primary" @click="magnify">
22
+            <Icon type="md-add" :size="18"/>
23
+          </Button>
24
+          <Button type="primary" @click="scale('X')">
25
+            <Icon custom="iconfont icon-shuipingfanzhuan" :size="18"/>
26
+          </Button>
27
+          <Button type="primary" @click="scale('Y')">
28
+            <Icon custom="iconfont icon-chuizhifanzhuan" :size="18"/>
29
+          </Button>
30
+          <Button type="primary" @click="move(0, -moveStep)">
31
+            <Icon type="md-arrow-round-up" :size="18"/>
32
+          </Button>
33
+          <Button type="primary" @click="move(-moveStep, 0)">
34
+            <Icon type="md-arrow-round-back" :size="18"/>
35
+          </Button>
36
+          <Button type="primary" @click="move(0, moveStep)">
37
+            <Icon type="md-arrow-round-down" :size="18"/>
38
+          </Button>
39
+          <Button type="primary" @click="move(moveStep, 0)">
40
+            <Icon type="md-arrow-round-forward" :size="18"/>
41
+          </Button>
42
+          <Button style="width: 150px;margin-top: 10px;" type="primary" @click="crop">{{ cropButtonText }}</Button>
43
+        </div>
44
+      </div>
45
+    </div>
46
+  </div>
47
+</template>
48
+
49
+<script>
50
+import Cropper from 'cropperjs'
51
+import './index.less'
52
+import 'cropperjs/dist/cropper.min.css'
53
+export default {
54
+  name: 'Cropper',
55
+  props: {
56
+    src: {
57
+      type: String,
58
+      default: ''
59
+    },
60
+    preview: {
61
+      type: Boolean,
62
+      default: true
63
+    },
64
+    moveStep: {
65
+      type: Number,
66
+      default: 4
67
+    },
68
+    cropButtonText: {
69
+      type: String,
70
+      default: '裁剪'
71
+    }
72
+  },
73
+  data () {
74
+    return {
75
+      cropper: null,
76
+      insideSrc: ''
77
+    }
78
+  },
79
+  computed: {
80
+    imgId () {
81
+      return `cropper${this._uid}`
82
+    },
83
+    previewId () {
84
+      return `cropper_preview${this._uid}`
85
+    }
86
+  },
87
+  watch: {
88
+    src (src) {
89
+      this.replace(src)
90
+    },
91
+    insideSrc (src) {
92
+      this.replace(src)
93
+    }
94
+  },
95
+  methods: {
96
+    beforeUpload (file) {
97
+      const reader = new FileReader()
98
+      reader.readAsDataURL(file)
99
+      reader.onload = (event) => {
100
+        this.insideSrc = event.srcElement.result
101
+      }
102
+      return false
103
+    },
104
+    replace (src) {
105
+      this.cropper.replace(src)
106
+      this.insideSrc = src
107
+    },
108
+    rotate () {
109
+      this.cropper.rotate(90)
110
+    },
111
+    shrink () {
112
+      this.cropper.zoom(-0.1)
113
+    },
114
+    magnify () {
115
+      this.cropper.zoom(0.1)
116
+    },
117
+    scale (d) {
118
+      this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
119
+    },
120
+    move (...argu) {
121
+      this.cropper.move(...argu)
122
+    },
123
+    crop () {
124
+      this.cropper.getCroppedCanvas().toBlob(blob => {
125
+        this.$emit('on-crop', blob)
126
+      })
127
+    }
128
+  },
129
+  mounted () {
130
+    this.$nextTick(() => {
131
+      let dom = document.getElementById(this.imgId)
132
+      this.cropper = new Cropper(dom, {
133
+        preview: `#${this.previewId}`,
134
+        checkCrossOrigin: true
135
+      })
136
+    })
137
+  }
138
+}
139
+</script>

+ 18
- 0
src/components/drag-drawer/drag-drawer-trigger.vue Visa fil

@@ -0,0 +1,18 @@
1
+<template>
2
+  <div :class="`${prefix}-move-trigger`">
3
+    <div :class="`${prefix}-move-trigger-point`">
4
+      <i></i><i></i><i></i><i></i><i></i>
5
+    </div>
6
+  </div>
7
+</template>
8
+
9
+<script>
10
+import Mixin from './mixin'
11
+export default {
12
+  name: 'DragDrawerTrigger',
13
+  mixins: [Mixin]
14
+}
15
+</script>
16
+
17
+<style>
18
+</style>

+ 156
- 0
src/components/drag-drawer/drag-drawer.vue Visa fil

@@ -0,0 +1,156 @@
1
+<template>
2
+  <Drawer ref="drawerWrapper"
3
+          :value="value"
4
+          @input="handleInput"
5
+          :width="width"
6
+          :class-name="outerClasses"
7
+          v-bind="$attrs"
8
+          v-on="$listeners">
9
+    <!-- 所有插槽内容显示在这里 ↓ -->
10
+
11
+    <template v-for="(slots, slotsName) in $slots">
12
+      <template v-if="slotsName !== 'default'">
13
+        <render-dom v-for="(render, index) in slots"
14
+                    :key="`b_drawer_${slotsName}_${index}`"
15
+                    :render="() => render"
16
+                    :slot="slotsName">
17
+        </render-dom>
18
+      </template>
19
+      <template v-else>
20
+        <div :class="`${prefix}-body-wrapper`"
21
+             :key="`b_drawer_${slotsName}`">
22
+          <render-dom v-for="(render, index) in slots"
23
+                      :key="`b_drawer_${slotsName}_${index}`"
24
+                      :render="() => render"
25
+                      :slot="slotsName">
26
+          </render-dom>
27
+        </div>
28
+      </template>
29
+    </template>
30
+    <!-- 所有插槽内容显示在这里 ↑ -->
31
+    <div v-if="draggable"
32
+         :style="triggerStyle"
33
+         :class="`${prefix}-trigger-wrapper`"
34
+         @mousedown="handleTriggerMousedown">
35
+      <slot name="trigger">
36
+        <drag-drawer-trigger></drag-drawer-trigger>
37
+      </slot>
38
+    </div>
39
+    <div v-if="$slots.footer"
40
+         :class="`${prefix}-footer`">
41
+      <slot name="footer"></slot>
42
+    </div>
43
+  </Drawer>
44
+</template>
45
+
46
+<script>
47
+import RenderDom from '@/libs/render-dom'
48
+import DragDrawerTrigger from './drag-drawer-trigger.vue'
49
+import Mixin from './mixin'
50
+import { on, off } from '@/libs/tools'
51
+import './index.less'
52
+export default {
53
+  name: 'BDrawer',
54
+  components: {
55
+    RenderDom,
56
+    DragDrawerTrigger
57
+  },
58
+  mixins: [Mixin],
59
+  props: {
60
+    value: {
61
+      type: Boolean,
62
+      default: false
63
+    },
64
+    width: {
65
+      type: [String, Number],
66
+      default: 256
67
+    },
68
+    // 是否可拖动修改宽度
69
+    draggable: {
70
+      type: Boolean,
71
+      default: false
72
+    },
73
+    // 最小拖动宽度
74
+    minWidth: {
75
+      type: [String, Number],
76
+      default: 256
77
+    }
78
+  },
79
+  data () {
80
+    return {
81
+      canMove: false,
82
+      wrapperWidth: 0,
83
+      wrapperLeft: 0
84
+    }
85
+  },
86
+  computed: {
87
+    outerClasses () {
88
+      const classesArray = [
89
+        `${this.prefix}-wrapper`,
90
+        this.canMove ? 'no-select pointer-events-none' : ''
91
+      ]
92
+      return classesArray.join(' ')
93
+    },
94
+    placement () {
95
+      return this.$attrs.placement
96
+    },
97
+    innerWidth () {
98
+      const width = this.width
99
+      return width <= 100 ? (this.wrapperWidth * width) / 100 : width
100
+    },
101
+    triggerStyle () {
102
+      return {
103
+        [this.placement]: `${this.innerWidth}px`,
104
+        position: this.$attrs.inner ? 'absolute' : 'fixed'
105
+      }
106
+    }
107
+  },
108
+  methods: {
109
+    handleInput (status) {
110
+      this.$emit('input', status)
111
+    },
112
+    handleTriggerMousedown (event) {
113
+      this.canMove = true
114
+      this.$emit('on-resize-start')
115
+      // 防止鼠标选中抽屉中文字,造成拖动trigger触发浏览器原生拖动行为
116
+      window.getSelection().removeAllRanges()
117
+    },
118
+    handleMousemove (event) {
119
+      if (!this.canMove) return
120
+      // 更新容器宽度和距离左侧页面距离,如果是window则距左侧距离为0
121
+      this.setWrapperWidth()
122
+      const left = event.pageX - this.wrapperLeft
123
+      // 如果抽屉方向为右边,宽度计算需用容器宽度减去left
124
+      let width = this.placement === 'right' ? this.wrapperWidth - left : left
125
+      // 限定做小宽度
126
+      width = Math.max(width, parseFloat(this.minWidth))
127
+      event.atMin = width === parseFloat(this.minWidth)
128
+      // 如果当前width不大于100,视为百分比
129
+      if (width <= 100) width = (width / this.wrapperWidth) * 100
130
+      this.$emit('update:width', parseInt(width))
131
+      this.$emit('on-resize', event)
132
+    },
133
+    handleMouseup (event) {
134
+      this.canMove = false
135
+      this.$emit('on-resize-end')
136
+    },
137
+    setWrapperWidth () {
138
+      const {
139
+        width,
140
+        left
141
+      } = this.$refs.drawerWrapper.$el.getBoundingClientRect()
142
+      this.wrapperWidth = width
143
+      this.wrapperLeft = left
144
+    }
145
+  },
146
+  mounted () {
147
+    on(document, 'mousemove', this.handleMousemove)
148
+    on(document, 'mouseup', this.handleMouseup)
149
+    this.setWrapperWidth()
150
+  },
151
+  beforeDestroy () {
152
+    off(document, 'mousemove', this.handleMousemove)
153
+    off(document, 'mouseup', this.handleMouseup)
154
+  }
155
+}
156
+</script>

+ 2
- 0
src/components/drag-drawer/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import DragDrawer from './drag-drawer.vue'
2
+export default DragDrawer

+ 70
- 0
src/components/drag-drawer/index.less Visa fil

@@ -0,0 +1,70 @@
1
+@prefix: ~"drag-drawer";
2
+@drag-drawer-trigger-height: 100px;
3
+@drag-drawer-trigger-width: 8px;
4
+
5
+.@{prefix}-wrapper{
6
+  &.no-select{
7
+    user-select: none;
8
+  }
9
+  &.pointer-events-none{
10
+    pointer-events: none;
11
+    & .@{prefix}-trigger-wrapper{
12
+      pointer-events: all;
13
+    }
14
+  }
15
+  .ivu-drawer{
16
+    &-header{
17
+      overflow: hidden !important;
18
+      box-sizing: border-box;
19
+    }
20
+    &-body{
21
+      padding: 0;
22
+      overflow: visible;
23
+      position: static;
24
+      display: flex;
25
+      flex-direction: column;
26
+    }
27
+  }
28
+  .@{prefix}-body-wrapper{
29
+    width: 100%;
30
+    height: 100%;
31
+    padding: 16px;
32
+    overflow: auto;
33
+  }
34
+  .@{prefix}-trigger-wrapper{
35
+    top: 0;
36
+    height: 100%;
37
+    width: 0;
38
+    .@{prefix}-move-trigger{
39
+      position: absolute;
40
+      top: 50%;
41
+      height: @drag-drawer-trigger-height;
42
+      width: @drag-drawer-trigger-width;
43
+      background: rgb(243, 243, 243);
44
+      transform: translate(-50%, -50%);
45
+      border-radius: ~"4px / 6px";
46
+      box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
47
+      line-height: @drag-drawer-trigger-height;
48
+      cursor: col-resize;
49
+      &-point{
50
+        display: inline-block;
51
+        width: 50%;
52
+        transform: translateX(50%);
53
+        i{
54
+          display: block;
55
+          border-bottom: 1px solid rgb(192, 192, 192);
56
+          padding-bottom: 2px;
57
+        }
58
+      }
59
+    }
60
+  }
61
+  .@{prefix}-footer{
62
+    flex-grow: 1;
63
+    width: 100%;
64
+    bottom: 0;
65
+    left: 0;
66
+    border-top: 1px solid #e8e8e8;
67
+    padding: 10px 16px;
68
+    background: #fff;
69
+  }
70
+}

+ 7
- 0
src/components/drag-drawer/mixin.js Visa fil

@@ -0,0 +1,7 @@
1
+export default {
2
+  data () {
3
+    return {
4
+      prefix: 'drag-drawer'
5
+    }
6
+  }
7
+}

+ 92
- 0
src/components/drag-list/drag-list.vue Visa fil

@@ -0,0 +1,92 @@
1
+<template>
2
+  <div class="drag-list-wrapper">
3
+    <div class="drag-list-con con1">
4
+      <slot name="left-title"></slot>
5
+      <draggable class="drop-box1" :class="dropConClass.left" :options="options" :value="list1" @input="handleListChange($event, 'left')" @end="handleEnd($event, 'left')">
6
+        <div class="drag-list-item" v-for="(itemLeft, index) in list1" :key="`drag_li1_${index}`">
7
+          <slot name="left" :itemLeft="itemLeft">{{ itemLeft }}</slot>
8
+        </div>
9
+      </draggable>
10
+    </div>
11
+    <div class="drag-list-con con2">
12
+      <slot name="right-title"></slot>
13
+      <draggable class="drop-box2" :class="dropConClass.right" :options="options" :value="list2" @input="handleListChange($event, 'right')" @end="handleEnd($event, 'right')">
14
+        <div class="drag-list-item" v-for="(itemRight, index) in list2" :key="`drag_li2_${index}`">
15
+          <slot name="right" :itemRight="itemRight">{{ itemRight }}</slot>
16
+        </div>
17
+      </draggable>
18
+    </div>
19
+  </div>
20
+</template>
21
+<script>
22
+import draggable from 'vuedraggable'
23
+export default {
24
+  name: 'DragList',
25
+  components: {
26
+    draggable
27
+  },
28
+  props: {
29
+    list1: {
30
+      type: Array,
31
+      required: true
32
+    },
33
+    list2: {
34
+      type: Array,
35
+      default: () => []
36
+    },
37
+    dropConClass: {
38
+      type: Object,
39
+      default: () => ({})
40
+    }
41
+  },
42
+  data () {
43
+    return {
44
+      options: { group: 'drag_list' }
45
+    }
46
+  },
47
+  methods: {
48
+    handleListChange (value, type) {
49
+      if (type === 'left') this.$emit('update:list1', value)
50
+      else this.$emit('update:list2', value)
51
+    },
52
+    handleEnd (event, type) {
53
+      const srcClassName = (event.srcElement || event.target).classList[0]
54
+      const targetClassName = event.to.classList[0]
55
+      let src = ''
56
+      let target = ''
57
+      if (srcClassName === targetClassName) {
58
+        if (type === 'left') {
59
+          src = 'left'
60
+          target = 'left'
61
+        } else {
62
+          src = 'right'
63
+          target = 'right'
64
+        }
65
+      } else {
66
+        if (type === 'left') {
67
+          src = 'left'
68
+          target = 'right'
69
+        } else {
70
+          src = 'right'
71
+          target = 'left'
72
+        }
73
+      }
74
+      this.$emit('on-change', {
75
+        src: src,
76
+        target: target,
77
+        oldIndex: event.oldIndex,
78
+        newIndex: event.newIndex
79
+      })
80
+    }
81
+  }
82
+}
83
+</script>
84
+<style lang="less">
85
+.drag-list-wrapper{
86
+  height: 100%;
87
+  .drag-list-con{
88
+    width: 50%;
89
+    float: left;
90
+  }
91
+}
92
+</style>

+ 2
- 0
src/components/drag-list/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import DragList from './drag-list.vue'
2
+export default DragList

+ 75
- 0
src/components/editor/editor.vue Visa fil

@@ -0,0 +1,75 @@
1
+<template>
2
+  <div class="editor-wrapper">
3
+    <div :id="editorId"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import Editor from 'wangeditor'
9
+import 'wangeditor/release/wangEditor.min.css'
10
+import { oneOf } from '@/libs/tools'
11
+export default {
12
+  name: 'Editor',
13
+  props: {
14
+    value: {
15
+      type: String,
16
+      default: ''
17
+    },
18
+    /**
19
+     * 绑定的值的类型, enum: ['html', 'text']
20
+     */
21
+    valueType: {
22
+      type: String,
23
+      default: 'html',
24
+      validator: (val) => {
25
+        return oneOf(val, ['html', 'text'])
26
+      }
27
+    },
28
+    /**
29
+     * @description 设置change事件触发时间间隔
30
+     */
31
+    changeInterval: {
32
+      type: Number,
33
+      default: 200
34
+    },
35
+    /**
36
+     * @description 是否开启本地存储
37
+     */
38
+    cache: {
39
+      type: Boolean,
40
+      default: true
41
+    }
42
+  },
43
+  computed: {
44
+    editorId () {
45
+      return `editor${this._uid}`
46
+    }
47
+  },
48
+  methods: {
49
+    setHtml (val) {
50
+      this.editor.txt.html(val)
51
+    }
52
+  },
53
+  mounted () {
54
+    this.editor = new Editor(`#${this.editorId}`)
55
+    this.editor.customConfig.onchange = (html) => {
56
+      let text = this.editor.txt.text()
57
+      if (this.cache) localStorage.editorCache = html
58
+      this.$emit('input', this.valueType === 'html' ? html : text)
59
+      this.$emit('on-change', html, text)
60
+    }
61
+    this.editor.customConfig.onchangeTimeout = this.changeInterval
62
+    // create这个方法一定要在所有配置项之后调用
63
+    this.editor.create()
64
+    // 如果本地有存储加载本地存储内容
65
+    let html = this.value || localStorage.editorCache
66
+    if (html) this.editor.txt.html(html)
67
+  }
68
+}
69
+</script>
70
+
71
+<style lang="less">
72
+.editor-wrapper *{
73
+  z-index: 100 !important;
74
+}
75
+</style>

+ 2
- 0
src/components/editor/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import Editor from './editor.vue'
2
+export default Editor

+ 35
- 0
src/components/icons/icons.vue Visa fil

@@ -0,0 +1,35 @@
1
+<template>
2
+  <i :class="`iconfont icon-${type}`" :style="styles"></i>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  name: 'Icons',
8
+  props: {
9
+    type: {
10
+      type: String,
11
+      required: true
12
+    },
13
+    color: {
14
+      type: String,
15
+      default: '#5c6b77'
16
+    },
17
+    size: {
18
+      type: Number,
19
+      default: 16
20
+    }
21
+  },
22
+  computed: {
23
+    styles () {
24
+      return {
25
+        fontSize: `${this.size}px`,
26
+        color: this.color
27
+      }
28
+    }
29
+  }
30
+}
31
+</script>
32
+
33
+<style>
34
+
35
+</style>

+ 2
- 0
src/components/icons/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import Icons from './icons.vue'
2
+export default Icons

+ 2
- 0
src/components/info-card/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import InforCard from './infor-card.vue'
2
+export default InforCard

+ 94
- 0
src/components/info-card/infor-card.vue Visa fil

@@ -0,0 +1,94 @@
1
+<template>
2
+  <Card :shadow="shadow" class="info-card-wrapper" :padding="0">
3
+    <div class="content-con">
4
+      <div class="left-area" :style="{background: color, width: leftWidth}">
5
+        <common-icon class="icon" :type="icon" :size="iconSize" color="#fff"/>
6
+      </div>
7
+      <div class="right-area" :style="{width: rightWidth}">
8
+        <div>
9
+          <slot></slot>
10
+        </div>
11
+      </div>
12
+    </div>
13
+  </Card>
14
+</template>
15
+
16
+<script>
17
+import CommonIcon from '_c/common-icon'
18
+export default {
19
+  name: 'InforCard',
20
+  components: {
21
+    CommonIcon
22
+  },
23
+  props: {
24
+    left: {
25
+      type: Number,
26
+      default: 36
27
+    },
28
+    color: {
29
+      type: String,
30
+      default: '#2d8cf0'
31
+    },
32
+    icon: {
33
+      type: String,
34
+      default: ''
35
+    },
36
+    iconSize: {
37
+      type: Number,
38
+      default: 20
39
+    },
40
+    shadow: {
41
+      type: Boolean,
42
+      default: false
43
+    }
44
+  },
45
+  computed: {
46
+    leftWidth () {
47
+      return `${this.left}%`
48
+    },
49
+    rightWidth () {
50
+      return `${100 - this.left}%`
51
+    }
52
+  }
53
+}
54
+</script>
55
+
56
+<style lang="less">
57
+.common{
58
+  float: left;
59
+  height: 100%;
60
+  display: table;
61
+  text-align: center;
62
+}
63
+.size{
64
+  width: 100%;
65
+  height: 100%;
66
+}
67
+.middle-center{
68
+  display: table-cell;
69
+  vertical-align: middle;
70
+}
71
+.info-card-wrapper{
72
+  .size;
73
+  overflow: hidden;
74
+  .ivu-card-body{
75
+    .size;
76
+  }
77
+  .content-con{
78
+    .size;
79
+    position: relative;
80
+    .left-area{
81
+      .common;
82
+      & > .icon{
83
+        .middle-center;
84
+      }
85
+    }
86
+    .right-area{
87
+      .common;
88
+      & > div{
89
+        .middle-center;
90
+      }
91
+    }
92
+  }
93
+}
94
+</style>

+ 2
- 0
src/components/login-form/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import LoginForm from './login-form.vue'
2
+export default LoginForm

+ 72
- 0
src/components/login-form/login-form.vue Visa fil

@@ -0,0 +1,72 @@
1
+<template>
2
+  <Form ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
3
+    <FormItem prop="userName">
4
+      <Input v-model="form.userName" placeholder="请输入用户名">
5
+        <span slot="prepend">
6
+          <Icon :size="16" type="ios-person"></Icon>
7
+        </span>
8
+      </Input>
9
+    </FormItem>
10
+    <FormItem prop="password">
11
+      <Input type="password" v-model="form.password" placeholder="请输入密码">
12
+        <span slot="prepend">
13
+          <Icon :size="14" type="md-lock"></Icon>
14
+        </span>
15
+      </Input>
16
+    </FormItem>
17
+    <FormItem>
18
+      <Button @click="handleSubmit" type="primary" long>登录</Button>
19
+    </FormItem>
20
+  </Form>
21
+</template>
22
+<script>
23
+export default {
24
+  name: 'LoginForm',
25
+  props: {
26
+    userNameRules: {
27
+      type: Array,
28
+      default: () => {
29
+        return [
30
+          { required: true, message: '账号不能为空', trigger: 'blur' }
31
+        ]
32
+      }
33
+    },
34
+    passwordRules: {
35
+      type: Array,
36
+      default: () => {
37
+        return [
38
+          { required: true, message: '密码不能为空', trigger: 'blur' }
39
+        ]
40
+      }
41
+    }
42
+  },
43
+  data () {
44
+    return {
45
+      form: {
46
+        userName: 'super_admin',
47
+        password: ''
48
+      }
49
+    }
50
+  },
51
+  computed: {
52
+    rules () { 
53
+      return {
54
+        userName: this.userNameRules,
55
+        password: this.passwordRules
56
+      }
57
+    }
58
+  },
59
+  methods: {
60
+    handleSubmit () {
61
+      this.$refs.loginForm.validate((valid) => {
62
+        if (valid) {
63
+          this.$emit('on-success-valid', {
64
+            userName: this.form.userName,
65
+            password: this.form.password
66
+          })
67
+        }
68
+      })
69
+    }
70
+  }
71
+}
72
+</script>

+ 2
- 0
src/components/main/components/a-back-top/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import ABackTop from './index.vue'
2
+export default ABackTop

+ 90
- 0
src/components/main/components/a-back-top/index.vue Visa fil

@@ -0,0 +1,90 @@
1
+<template>
2
+    <div :class="classes" :style="styles" @click="back">
3
+        <slot>
4
+            <div :class="innerClasses">
5
+                <i class="ivu-icon ivu-icon-ios-arrow-up"></i>
6
+            </div>
7
+        </slot>
8
+    </div>
9
+</template>
10
+<script>
11
+import { scrollTop } from '@/libs/util'
12
+import { on, off } from '@/libs/tools'
13
+const prefixCls = 'ivu-back-top'
14
+
15
+export default {
16
+  name: 'ABackTop',
17
+  props: {
18
+    height: {
19
+      type: Number,
20
+      default: 400
21
+    },
22
+    bottom: {
23
+      type: Number,
24
+      default: 30
25
+    },
26
+    right: {
27
+      type: Number,
28
+      default: 30
29
+    },
30
+    duration: {
31
+      type: Number,
32
+      default: 1000
33
+    },
34
+    container: {
35
+      type: null,
36
+      default: window
37
+    }
38
+  },
39
+  data () {
40
+    return {
41
+      backTop: false
42
+    }
43
+  },
44
+  mounted () {
45
+    // window.addEventListener('scroll', this.handleScroll, false)
46
+    // window.addEventListener('resize', this.handleScroll, false)
47
+    on(this.containerEle, 'scroll', this.handleScroll)
48
+    on(this.containerEle, 'resize', this.handleScroll)
49
+  },
50
+  beforeDestroy () {
51
+    // window.removeEventListener('scroll', this.handleScroll, false)
52
+    // window.removeEventListener('resize', this.handleScroll, false)
53
+    off(this.containerEle, 'scroll', this.handleScroll)
54
+    off(this.containerEle, 'resize', this.handleScroll)
55
+  },
56
+  computed: {
57
+    classes () {
58
+      return [
59
+        `${prefixCls}`,
60
+        {
61
+          [`${prefixCls}-show`]: this.backTop
62
+        }
63
+      ]
64
+    },
65
+    styles () {
66
+      return {
67
+        bottom: `${this.bottom}px`,
68
+        right: `${this.right}px`
69
+      }
70
+    },
71
+    innerClasses () {
72
+      return `${prefixCls}-inner`
73
+    },
74
+    containerEle () {
75
+      return this.container === window ? window : document.querySelector(this.container)
76
+    }
77
+  },
78
+  methods: {
79
+    handleScroll () {
80
+      this.backTop = this.containerEle.scrollTop >= this.height
81
+    },
82
+    back () {
83
+      let target = typeof this.container === 'string' ? this.containerEle : (document.documentElement || document.body)
84
+      const sTop = target.scrollTop
85
+      scrollTop(this.containerEle, sTop, 0, this.duration)
86
+      this.$emit('on-click')
87
+    }
88
+  }
89
+}
90
+</script>

+ 49
- 0
src/components/main/components/error-store/error-store.vue Visa fil

@@ -0,0 +1,49 @@
1
+<template>
2
+  <div class="error-store">
3
+    <Badge dot :count="countComputed">
4
+      <Button type="text" @click="openErrorLoggerPage">
5
+        <Icon :size="20" type="ios-bug"/>
6
+      </Button>
7
+    </Badge>
8
+  </div>
9
+</template>
10
+
11
+<script>
12
+export default {
13
+  name: 'ErrorStore',
14
+  props: {
15
+    count: {
16
+      type: Number,
17
+      default: 0
18
+    },
19
+    hasRead: {
20
+      type: Boolean,
21
+      default: false
22
+    }
23
+  },
24
+  computed: {
25
+    countComputed () {
26
+      return this.hasRead ? 0 : this.count
27
+    }
28
+  },
29
+  methods: {
30
+    openErrorLoggerPage () {
31
+      this.$router.push({
32
+        name: 'error_logger_page'
33
+      })
34
+    }
35
+  }
36
+}
37
+</script>
38
+
39
+<style lang="less">
40
+.error-store{
41
+  margin-right: 12px;
42
+  .ivu-badge-dot{
43
+    top: 20px;
44
+  }
45
+  .ivu-btn.ivu-btn-text{
46
+    padding: 5px 1px 6px;
47
+  }
48
+}
49
+</style>

+ 2
- 0
src/components/main/components/error-store/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import ErrorStore from './error-store.vue'
2
+export default ErrorStore

+ 84
- 0
src/components/main/components/fullscreen/fullscreen.vue Visa fil

@@ -0,0 +1,84 @@
1
+<template>
2
+  <div v-if="showFullScreenBtn" class="full-screen-btn-con">
3
+    <Tooltip :content="value ? '退出全屏' : '全屏'" placement="bottom">
4
+      <Icon @click.native="handleChange" :type="value ? 'md-contract' : 'md-expand'" :size="23"></Icon>
5
+    </Tooltip>
6
+  </div>
7
+</template>
8
+
9
+<script>
10
+export default {
11
+  name: 'Fullscreen',
12
+  computed: {
13
+    showFullScreenBtn () {
14
+      return window.navigator.userAgent.indexOf('MSIE') < 0
15
+    }
16
+  },
17
+  props: {
18
+    value: {
19
+      type: Boolean,
20
+      default: false
21
+    }
22
+  },
23
+  methods: {
24
+    handleFullscreen () {
25
+      let main = document.body
26
+      if (this.value) {
27
+        if (document.exitFullscreen) {
28
+          document.exitFullscreen()
29
+        } else if (document.mozCancelFullScreen) {
30
+          document.mozCancelFullScreen()
31
+        } else if (document.webkitCancelFullScreen) {
32
+          document.webkitCancelFullScreen()
33
+        } else if (document.msExitFullscreen) {
34
+          document.msExitFullscreen()
35
+        }
36
+      } else {
37
+        if (main.requestFullscreen) {
38
+          main.requestFullscreen()
39
+        } else if (main.mozRequestFullScreen) {
40
+          main.mozRequestFullScreen()
41
+        } else if (main.webkitRequestFullScreen) {
42
+          main.webkitRequestFullScreen()
43
+        } else if (main.msRequestFullscreen) {
44
+          main.msRequestFullscreen()
45
+        }
46
+      }
47
+    },
48
+    handleChange () {
49
+      this.handleFullscreen()
50
+    }
51
+  },
52
+  mounted () {
53
+    let isFullscreen = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen
54
+    isFullscreen = !!isFullscreen
55
+    document.addEventListener('fullscreenchange', () => {
56
+      this.$emit('input', !this.value)
57
+      this.$emit('on-change', !this.value)
58
+    })
59
+    document.addEventListener('mozfullscreenchange', () => {
60
+      this.$emit('input', !this.value)
61
+      this.$emit('on-change', !this.value)
62
+    })
63
+    document.addEventListener('webkitfullscreenchange', () => {
64
+      this.$emit('input', !this.value)
65
+      this.$emit('on-change', !this.value)
66
+    })
67
+    document.addEventListener('msfullscreenchange', () => {
68
+      this.$emit('input', !this.value)
69
+      this.$emit('on-change', !this.value)
70
+    })
71
+    this.$emit('input', isFullscreen)
72
+  }
73
+}
74
+</script>
75
+
76
+<style lang="less">
77
+.full-screen-btn-con .ivu-tooltip-rel{
78
+  height: 64px;
79
+  line-height: 56px;
80
+  i{
81
+    cursor: pointer;
82
+  }
83
+}
84
+</style>

+ 2
- 0
src/components/main/components/fullscreen/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import Fullscreen from './fullscreen.vue'
2
+export default Fullscreen

+ 4
- 0
src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less Visa fil

@@ -0,0 +1,4 @@
1
+.custom-bread-crumb{
2
+  display: inline-block;
3
+  vertical-align: top;
4
+}

+ 46
- 0
src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue Visa fil

@@ -0,0 +1,46 @@
1
+<template>
2
+  <div class="custom-bread-crumb">
3
+    <Breadcrumb :style="{fontSize: `${fontSize}px`}" separator=">">
4
+      <BreadcrumbItem v-for="item in list" :to="item.to" :key="`bread-crumb-${item.name}`">
5
+        <common-icon style="margin-right: 4px;" :type="item.icon || ''"/>
6
+        {{ showTitle(item) }}
7
+      </BreadcrumbItem>
8
+    </Breadcrumb>
9
+  </div>
10
+</template>
11
+<script>
12
+import { showTitle } from '@/libs/util'
13
+import CommonIcon from '_c/common-icon'
14
+import './custom-bread-crumb.less'
15
+export default {
16
+  name: 'customBreadCrumb',
17
+  components: {
18
+    CommonIcon
19
+  },
20
+  props: {
21
+    list: {
22
+      type: Array,
23
+      default: () => []
24
+    },
25
+    fontSize: {
26
+      type: Number,
27
+      default: 14
28
+    },
29
+    showIcon: {
30
+      type: Boolean,
31
+      default: false
32
+    }
33
+  },
34
+  methods: {
35
+    showTitle (item) {
36
+      return showTitle(item, this)
37
+    },
38
+    isCustomIcon (iconName) {
39
+      return iconName.indexOf('_') === 0
40
+    },
41
+    getCustomIconName (iconName) {
42
+      return iconName.slice(1)
43
+    }
44
+  }
45
+}
46
+</script>

+ 2
- 0
src/components/main/components/header-bar/custom-bread-crumb/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import customBreadCrumb from './custom-bread-crumb.vue'
2
+export default customBreadCrumb

+ 14
- 0
src/components/main/components/header-bar/header-bar.less Visa fil

@@ -0,0 +1,14 @@
1
+.header-bar{
2
+  width: 100%;
3
+  height: 100%;
4
+  position: relative;
5
+  .custom-content-con{
6
+    float: right;
7
+    height: auto;
8
+    padding-right: 20px;
9
+    line-height: 64px;
10
+    & > *{
11
+      float: right;
12
+    }
13
+  }
14
+}

+ 34
- 0
src/components/main/components/header-bar/header-bar.vue Visa fil

@@ -0,0 +1,34 @@
1
+<template>
2
+  <div class="header-bar">
3
+    <sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>
4
+    <custom-bread-crumb show-icon style="margin-left: 30px;" :list="breadCrumbList"></custom-bread-crumb>
5
+    <div class="custom-content-con">
6
+      <slot></slot>
7
+    </div>
8
+  </div>
9
+</template>
10
+<script>
11
+import siderTrigger from './sider-trigger'
12
+import customBreadCrumb from './custom-bread-crumb'
13
+import './header-bar.less'
14
+export default {
15
+  name: 'HeaderBar',
16
+  components: {
17
+    siderTrigger,
18
+    customBreadCrumb
19
+  },
20
+  props: {
21
+    collapsed: Boolean
22
+  },
23
+  computed: {
24
+    breadCrumbList () {
25
+      return this.$store.state.app.breadCrumbList
26
+    }
27
+  },
28
+  methods: {
29
+    handleCollpasedChange (state) {
30
+      this.$emit('on-coll-change', state)
31
+    }
32
+  }
33
+}
34
+</script>

+ 2
- 0
src/components/main/components/header-bar/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import HeaderBar from './header-bar'
2
+export default HeaderBar

+ 2
- 0
src/components/main/components/header-bar/sider-trigger/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import siderTrigger from './sider-trigger.vue'
2
+export default siderTrigger

+ 21
- 0
src/components/main/components/header-bar/sider-trigger/sider-trigger.less Visa fil

@@ -0,0 +1,21 @@
1
+.trans{
2
+  transition: transform .2s ease;
3
+}
4
+@size: 40px;
5
+.sider-trigger-a{
6
+  padding: 6px;
7
+  width: @size;
8
+  height: @size;
9
+  display: inline-block;
10
+  text-align: center;
11
+  color: #5c6b77;
12
+  margin-top: 12px;
13
+  i{
14
+    .trans;
15
+    vertical-align: top;
16
+  }
17
+  &.collapsed i{
18
+    transform: rotateZ(90deg);
19
+    .trans;
20
+  }
21
+}

+ 27
- 0
src/components/main/components/header-bar/sider-trigger/sider-trigger.vue Visa fil

@@ -0,0 +1,27 @@
1
+<template>
2
+  <a @click="handleChange" type="text" :class="['sider-trigger-a', collapsed ? 'collapsed' : '']"><Icon :type="icon" :size="size" /></a>
3
+</template>
4
+<script>
5
+export default {
6
+  name: 'siderTrigger',
7
+  props: {
8
+    collapsed: Boolean,
9
+    icon: {
10
+      type: String,
11
+      default: 'navicon-round'
12
+    },
13
+    size: {
14
+      type: Number,
15
+      default: 26
16
+    }
17
+  },
18
+  methods: {
19
+    handleChange () {
20
+      this.$emit('on-change', !this.collapsed)
21
+    }
22
+  }
23
+}
24
+</script>
25
+<style lang="less">
26
+@import './sider-trigger.less';
27
+</style>

+ 2
- 0
src/components/main/components/language/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import Language from './language.vue'
2
+export default Language

+ 51
- 0
src/components/main/components/language/language.vue Visa fil

@@ -0,0 +1,51 @@
1
+<template>
2
+  <div>
3
+    <Dropdown trigger="click" @on-click="selectLang">
4
+      <a href="javascript:void(0)">
5
+        {{ title }}
6
+        <Icon :size="18" type="md-arrow-dropdown" />
7
+      </a>
8
+      <DropdownMenu slot="list">
9
+        <DropdownItem v-for="(value, key) in localList" :name="key" :key="`lang-${key}`">{{ value }}</DropdownItem>
10
+      </DropdownMenu>
11
+    </Dropdown>
12
+  </div>
13
+</template>
14
+
15
+<script>
16
+export default {
17
+  name: 'Language',
18
+  props: {
19
+    lang: String
20
+  },
21
+  data () {
22
+    return {
23
+      langList: {
24
+        'zh-CN': '语言',
25
+        'zh-TW': '語言',
26
+        'en-US': 'Lang'
27
+      },
28
+      localList: {
29
+        'zh-CN': '中文简体',
30
+        'zh-TW': '中文繁体',
31
+        'en-US': 'English'
32
+      }
33
+    }
34
+  },
35
+  watch: {
36
+    lang (lang) {
37
+      this.$i18n.locale = lang
38
+    }
39
+  },
40
+  computed: {
41
+    title () {
42
+      return this.langList[this.lang]
43
+    }
44
+  },
45
+  methods: {
46
+    selectLang (name) {
47
+      this.$emit('on-lang-change', name)
48
+    }
49
+  }
50
+}
51
+</script>

+ 51
- 0
src/components/main/components/side-menu/collapsed-menu.vue Visa fil

@@ -0,0 +1,51 @@
1
+<template>
2
+  <Dropdown ref="dropdown" @on-click="handleClick" :class="hideTitle ? '' : 'collased-menu-dropdown'" :transfer="hideTitle" :placement="placement">
3
+    <a class="drop-menu-a" type="text" @mouseover="handleMousemove($event, children)" :style="{textAlign: !hideTitle ? 'left' : ''}"><common-icon :size="rootIconSize" :color="textColor" :type="parentItem.icon"/><span class="menu-title" v-if="!hideTitle">{{ showTitle(parentItem) }}</span><Icon style="float: right;" v-if="!hideTitle" type="ios-arrow-forward" :size="16"/></a>
4
+    <DropdownMenu ref="dropdown" slot="list">
5
+      <template v-for="child in children">
6
+        <collapsed-menu v-if="showChildren(child)" :icon-size="iconSize" :parent-item="child" :key="`drop-${child.name}`"></collapsed-menu>
7
+        <DropdownItem v-else :key="`drop-${child.name}`" :name="child.name"><common-icon :size="iconSize" :type="child.icon"/><span class="menu-title">{{ showTitle(child) }}</span></DropdownItem>
8
+      </template>
9
+    </DropdownMenu>
10
+  </Dropdown>
11
+</template>
12
+<script>
13
+import mixin from './mixin'
14
+import itemMixin from './item-mixin'
15
+import { findNodeUpperByClasses } from '@/libs/util'
16
+
17
+export default {
18
+  name: 'CollapsedMenu',
19
+  mixins: [ mixin, itemMixin ],
20
+  props: {
21
+    hideTitle: {
22
+      type: Boolean,
23
+      default: false
24
+    },
25
+    rootIconSize: {
26
+      type: Number,
27
+      default: 16
28
+    }
29
+  },
30
+  data () {
31
+    return {
32
+      placement: 'right-end'
33
+    }
34
+  },
35
+  methods: {
36
+    handleClick (name) {
37
+      this.$emit('on-click', name)
38
+    },
39
+    handleMousemove (event, children) {
40
+      const { pageY } = event
41
+      const height = children.length * 38
42
+      const isOverflow = pageY + height < window.innerHeight
43
+      this.placement = isOverflow ? 'right-start' : 'right-end'
44
+    }
45
+  },
46
+  mounted () {
47
+    let dropdown = findNodeUpperByClasses(this.$refs.dropdown.$el, ['ivu-select-dropdown', 'ivu-dropdown-transfer'])
48
+    if (dropdown) dropdown.style.overflow = 'visible'
49
+  }
50
+}
51
+</script>

+ 2
- 0
src/components/main/components/side-menu/index.js Visa fil

@@ -0,0 +1,2 @@
1
+import SideMenu from './side-menu.vue'
2
+export default SideMenu

+ 21
- 0
src/components/main/components/side-menu/item-mixin.js Visa fil

@@ -0,0 +1,21 @@
1
+export default {
2
+  props: {
3
+    parentItem: {
4
+      type: Object,
5
+      default: () => {}
6
+    },
7
+    theme: String,
8
+    iconSize: Number
9
+  },
10
+  computed: {
11
+    parentName () {
12
+      return this.parentItem.name
13
+    },
14
+    children () {
15
+      return this.parentItem.children
16
+    },
17
+    textColor () {
18
+      return this.theme === 'dark' ? '#fff' : '#495060'
19
+    }
20
+  }
21
+}

+ 18
- 0
src/components/main/components/side-menu/mixin.js Visa fil

@@ -0,0 +1,18 @@
1
+import CommonIcon from '_c/common-icon'
2
+import { showTitle } from '@/libs/util'
3
+export default {
4
+  components: {
5
+    CommonIcon
6
+  },
7
+  methods: {
8
+    showTitle (item) {
9
+      return showTitle(item, this)
10
+    },
11
+    showChildren (item) {
12
+      return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways))
13
+    },
14
+    getNameOrHref (item, children0) {
15
+      return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name)
16
+    }
17
+  }
18
+}

+ 26
- 0
src/components/main/components/side-menu/side-menu-item.vue Visa fil

@@ -0,0 +1,26 @@
1
+<template>
2
+  <Submenu :name="`${parentName}`">
3
+    <template slot="title">
4
+      <common-icon :type="parentItem.icon || ''"/>
5
+      <span>{{ showTitle(parentItem) }}</span>
6
+    </template>
7
+    <template v-for="item in children">
8
+      <template v-if="item.children && item.children.length === 1">
9
+        <side-menu-item v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></side-menu-item>
10
+        <menu-item v-else :name="getNameOrHref(item, true)" :key="`menu-${item.children[0].name}`"><common-icon :type="item.children[0].icon || ''"/><span>{{ showTitle(item.children[0]) }}</span></menu-item>
11
+      </template>
12
+      <template v-else>
13
+        <side-menu-item v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></side-menu-item>
14
+        <menu-item v-else :name="getNameOrHref(item)" :key="`menu-${item.name}`"><common-icon :type="item.icon || ''"/><span>{{ showTitle(item) }}</span></menu-item>
15
+      </template>
16
+    </template>
17
+  </Submenu>
18
+</template>
19
+<script>
20
+import mixin from './mixin'
21
+import itemMixin from './item-mixin'
22
+export default {
23
+  name: 'SideMenuItem',
24
+  mixins: [ mixin, itemMixin ]
25
+}
26
+</script>

+ 73
- 0
src/components/main/components/side-menu/side-menu.less Visa fil

@@ -0,0 +1,73 @@
1
+.side-menu-wrapper{
2
+  user-select: none;
3
+  .menu-collapsed{
4
+    padding-top: 10px;
5
+
6
+    .ivu-dropdown{
7
+      width: 100%;
8
+      .ivu-dropdown-rel a{
9
+        width: 100%;
10
+      }
11
+    }
12
+    .ivu-tooltip{
13
+      width: 100%;
14
+      .ivu-tooltip-rel{
15
+        width: 100%;
16
+      }
17
+      .ivu-tooltip-popper .ivu-tooltip-content{
18
+        .ivu-tooltip-arrow{
19
+          border-right-color: #fff;
20
+        }
21
+        .ivu-tooltip-inner{
22
+          background: #fff;
23
+          color: #495060;
24
+        }
25
+      }
26
+    }
27
+
28
+
29
+  }
30
+  a.drop-menu-a{
31
+    display: inline-block;
32
+    padding: 6px 15px;
33
+    width: 100%;
34
+    text-align: center;
35
+    color: #495060;
36
+  }
37
+}
38
+.menu-title{
39
+  padding-left: 6px;
40
+}
41
+// .ivu-menu /deep/ .ivu-menu-item-active{
42
+//   color: #f0faff;
43
+//   background: #2d8cf0;
44
+// }
45
+.ivu-menu-item{
46
+  margin: 0 40px;
47
+  border-radius: 12px;
48
+}
49
+div /deep/ .ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu){
50
+  color: #f0faff;
51
+  background: #2d8cf0;
52
+}
53
+div /deep/ .ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu)::after {
54
+  content: '';
55
+  display: block;
56
+  height: 26px;
57
+  margin: 12px 0 0 -34px;
58
+  width: 4px;
59
+  position: absolute;
60
+  top: 0;
61
+  bottom: 0;
62
+  left:0;
63
+  background: #2d8cf0;
64
+}
65
+.ivu-menu-submenu-title{
66
+  margin: 0 40px;
67
+}
68
+div /deep/ .ivu-menu-vertical.ivu-menu-light:after{
69
+  width: 0;
70
+}
71
+div /deep/ .ivu-layout{
72
+  background-color: #EEF5FB;
73
+}

+ 0
- 0
src/components/main/components/side-menu/side-menu.vue Visa fil


Vissa filer visades inte eftersom för många filer har ändrats

Laddar…
Avbryt
Spara