Browse Source

初始化

sunny 1 year ago
commit
4d8f5f16f0
100 changed files with 4358 additions and 0 deletions
  1. 12 0
      .babelrc
  2. 14 0
      .editorconfig
  3. 3 0
      .eslintignore
  4. 199 0
      .eslintrc.js
  5. 19 0
      .gitignore
  6. 10 0
      .postcssrc.js
  7. 5 0
      .travis.yml
  8. 48 0
      build/build.js
  9. 54 0
      build/check-versions.js
  10. BIN
      build/logo.png
  11. 101 0
      build/utils.js
  12. 22 0
      build/vue-loader.conf.js
  13. 101 0
      build/webpack.base.conf.js
  14. 88 0
      build/webpack.dev.conf.js
  15. 175 0
      build/webpack.prod.conf.js
  16. 9 0
      config/dev.env.js
  17. 83 0
      config/index.js
  18. 12 0
      config/prod.env.js
  19. BIN
      favicon.ico
  20. 15 0
      index.html
  21. 90 0
      package.json
  22. 29 0
      src/App.vue
  23. 41 0
      src/api/activitytag.js
  24. 57 0
      src/api/admin.js
  25. 10 0
      src/api/approvehistory.js
  26. 41 0
      src/api/banner.js
  27. 9 0
      src/api/dashboard.js
  28. 37 0
      src/api/login.js
  29. 87 0
      src/api/news.js
  30. 49 0
      src/api/newsCenter.js
  31. 75 0
      src/api/organize.js
  32. 36 0
      src/api/organizeuser.js
  33. 41 0
      src/api/questionDetail.js
  34. 41 0
      src/api/questionSort.js
  35. 50 0
      src/api/questions.js
  36. 73 0
      src/api/role.js
  37. 71 0
      src/api/storage.js
  38. 17 0
      src/api/trend.js
  39. 108 0
      src/api/user.js
  40. 25 0
      src/api/visitor.js
  41. 26 0
      src/api/welfare.js
  42. BIN
      src/assets/401_images/401.gif
  43. BIN
      src/assets/404_images/404.png
  44. BIN
      src/assets/404_images/404_cloud.png
  45. 199 0
      src/assets/echarts-macarons.js
  46. 112 0
      src/components/BackToTop/index.vue
  47. 52 0
      src/components/Breadcrumb/index.vue
  48. 150 0
      src/components/Charts/keyboard.vue
  49. 225 0
      src/components/Charts/lineMarker.vue
  50. 268 0
      src/components/Charts/mixChart.vue
  51. 45 0
      src/components/Hamburger/index.vue
  52. 65 0
      src/components/Screenfull/index.vue
  53. 57 0
      src/components/ScrollBar/index.vue
  54. 72 0
      src/components/ScrollPane/index.vue
  55. 76 0
      src/components/Sticky/index.vue
  56. 42 0
      src/components/SvgIcon/index.vue
  57. 181 0
      src/components/Tinymce/index.vue
  58. 7 0
      src/components/Tinymce/plugins.js
  59. 6 0
      src/components/Tinymce/toolbar.js
  60. 123 0
      src/components/Upload/singleImage.vue
  61. 118 0
      src/components/Upload/singleImage2.vue
  62. 145 0
      src/components/Upload/singleImage3.vue
  63. 91 0
      src/directive/sticky.js
  64. 13 0
      src/directive/waves/index.js
  65. 26 0
      src/directive/waves/waves.css
  66. 42 0
      src/directive/waves/waves.js
  67. 9 0
      src/icons/index.js
  68. 1 0
      src/icons/svg/404.svg
  69. 1 0
      src/icons/svg/bug.svg
  70. 1 0
      src/icons/svg/chart.svg
  71. 1 0
      src/icons/svg/clipboard.svg
  72. 1 0
      src/icons/svg/component.svg
  73. 1 0
      src/icons/svg/dashboard.svg
  74. 1 0
      src/icons/svg/documentation.svg
  75. 1 0
      src/icons/svg/drag.svg
  76. 43 0
      src/icons/svg/edit.svg
  77. 1 0
      src/icons/svg/email.svg
  78. 1 0
      src/icons/svg/example.svg
  79. 1 0
      src/icons/svg/excel.svg
  80. 1 0
      src/icons/svg/eye.svg
  81. 1 0
      src/icons/svg/form.svg
  82. 72 0
      src/icons/svg/group.svg
  83. 1 0
      src/icons/svg/icon.svg
  84. 1 0
      src/icons/svg/international.svg
  85. 1 0
      src/icons/svg/language.svg
  86. 1 0
      src/icons/svg/lock.svg
  87. 52 0
      src/icons/svg/magnifying-glass.svg
  88. 1 0
      src/icons/svg/message.svg
  89. 1 0
      src/icons/svg/money.svg
  90. 1 0
      src/icons/svg/password.svg
  91. 1 0
      src/icons/svg/people.svg
  92. 1 0
      src/icons/svg/peoples.svg
  93. 1 0
      src/icons/svg/qq.svg
  94. 56 0
      src/icons/svg/raise-your-hand-to-ask.svg
  95. 1 0
      src/icons/svg/shoppingCard.svg
  96. 1 0
      src/icons/svg/star.svg
  97. 1 0
      src/icons/svg/tab.svg
  98. 1 0
      src/icons/svg/table.svg
  99. 1 0
      src/icons/svg/theme.svg
  100. 0 0
      src/icons/svg/user.svg

+ 12 - 0
.babelrc

@@ -0,0 +1,12 @@
+{
+  "presets": [
+    ["env", {
+      "modules": false,
+      "targets": {
+        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+      }
+    }],
+    "stage-2"
+  ],
+  "plugins": ["transform-vue-jsx", "transform-runtime"]
+}

+ 14 - 0
.editorconfig

@@ -0,0 +1,14 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false

+ 3 - 0
.eslintignore

@@ -0,0 +1,3 @@
+build/*.js
+config/*.js
+src/assets

+ 199 - 0
.eslintrc.js

@@ -0,0 +1,199 @@
+module.exports = {
+  root: true,
+  parser: 'babel-eslint',
+  parserOptions: {
+    sourceType: 'module'
+  },
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  extends: 'eslint:recommended',
+  // required to lint *.vue files
+  plugins: [
+    'html'
+  ],
+  // check if imports actually resolve
+  'settings': {
+    'import/resolver': {
+      'webpack': {
+        'config': 'build/webpack.base.conf.js'
+      }
+    }
+  },
+  // add your custom rules here
+  //it is base on https://github.com/vuejs/eslint-config-vue
+  'rules': {
+    'accessor-pairs': 2,
+    'arrow-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'block-spacing': [2, 'always'],
+    'brace-style': [2, '1tbs', {
+      'allowSingleLine': true
+    }],
+    'camelcase': [0, {
+      'properties': 'always'
+    }],
+    'comma-dangle': [2, 'never'],
+    'comma-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'comma-style': [2, 'last'],
+    'constructor-super': 2,
+    'curly': [2, 'multi-line'],
+    'dot-location': [2, 'property'],
+    'eol-last': 2,
+    'eqeqeq': [2, 'allow-null'],
+    'generator-star-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'handle-callback-err': [2, '^(err|error)$'],
+    'indent': [2, 2, {
+      'SwitchCase': 1
+    }],
+    'jsx-quotes': [2, 'prefer-single'],
+    'key-spacing': [2, {
+      'beforeColon': false,
+      'afterColon': true
+    }],
+    'keyword-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'new-cap': [2, {
+      'newIsCap': true,
+      'capIsNew': false
+    }],
+    'new-parens': 2,
+    'no-array-constructor': 2,
+    'no-caller': 2,
+    'no-console': 'off',
+    'no-class-assign': 2,
+    'no-cond-assign': 2,
+    'no-const-assign': 2,
+    'no-control-regex': 0,
+    'no-delete-var': 2,
+    'no-dupe-args': 2,
+    'no-dupe-class-members': 2,
+    'no-dupe-keys': 2,
+    'no-duplicate-case': 2,
+    'no-empty-character-class': 2,
+    'no-empty-pattern': 2,
+    'no-eval': 2,
+    'no-ex-assign': 2,
+    'no-extend-native': 2,
+    'no-extra-bind': 2,
+    'no-extra-boolean-cast': 2,
+    'no-extra-parens': [2, 'functions'],
+    'no-fallthrough': 2,
+    'no-floating-decimal': 2,
+    'no-func-assign': 2,
+    'no-implied-eval': 2,
+    'no-inner-declarations': [2, 'functions'],
+    'no-invalid-regexp': 2,
+    'no-irregular-whitespace': 2,
+    'no-iterator': 2,
+    'no-label-var': 2,
+    'no-labels': [2, {
+      'allowLoop': false,
+      'allowSwitch': false
+    }],
+    'no-lone-blocks': 2,
+    'no-mixed-spaces-and-tabs': 2,
+    'no-multi-spaces': 2,
+    'no-multi-str': 2,
+    'no-multiple-empty-lines': [2, {
+      'max': 1
+    }],
+    'no-native-reassign': 2,
+    'no-negated-in-lhs': 2,
+    'no-new-object': 2,
+    'no-new-require': 2,
+    'no-new-symbol': 2,
+    'no-new-wrappers': 2,
+    'no-obj-calls': 2,
+    'no-octal': 2,
+    'no-octal-escape': 2,
+    'no-path-concat': 2,
+    'no-proto': 2,
+    'no-redeclare': 2,
+    'no-regex-spaces': 2,
+    'no-return-assign': [2, 'except-parens'],
+    'no-self-assign': 2,
+    'no-self-compare': 2,
+    'no-sequences': 2,
+    'no-shadow-restricted-names': 2,
+    'no-spaced-func': 2,
+    'no-sparse-arrays': 2,
+    'no-this-before-super': 2,
+    'no-throw-literal': 2,
+    'no-trailing-spaces': 2,
+    'no-undef': 2,
+    'no-undef-init': 2,
+    'no-unexpected-multiline': 2,
+    'no-unmodified-loop-condition': 2,
+    'no-unneeded-ternary': [2, {
+      'defaultAssignment': false
+    }],
+    'no-unreachable': 2,
+    'no-unsafe-finally': 2,
+    'no-unused-vars': [2, {
+      'vars': 'all',
+      'args': 'none'
+    }],
+    'no-useless-call': 2,
+    'no-useless-computed-key': 2,
+    'no-useless-constructor': 2,
+    'no-useless-escape': 0,
+    'no-whitespace-before-property': 2,
+    'no-with': 2,
+    'one-var': [2, {
+      'initialized': 'never'
+    }],
+    'operator-linebreak': [2, 'after', {
+      'overrides': {
+        '?': 'before',
+        ':': 'before'
+      }
+    }],
+    'padded-blocks': [2, 'never'],
+    'quotes': [2, 'single', {
+      'avoidEscape': true,
+      'allowTemplateLiterals': true
+    }],
+    'semi': [2, 'never'],
+    'semi-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'space-before-blocks': [2, 'always'],
+    'space-before-function-paren': [2, 'never'],
+    'space-in-parens': [2, 'never'],
+    'space-infix-ops': 2,
+    'space-unary-ops': [2, {
+      'words': true,
+      'nonwords': false
+    }],
+    'spaced-comment': [2, 'always', {
+      'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+    }],
+    'template-curly-spacing': [2, 'never'],
+    'use-isnan': 2,
+    'valid-typeof': 2,
+    'wrap-iife': [2, 'any'],
+    'yield-star-spacing': [2, 'both'],
+    'yoda': [2, 'never'],
+    'prefer-const': 2,
+    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+    'object-curly-spacing': [2, 'always', {
+      objectsInObjects: false
+    }],
+    'array-bracket-spacing': [2, 'never']
+  }
+}
+

+ 19 - 0
.gitignore

@@ -0,0 +1,19 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+test/unit/coverage
+test/e2e/reports
+selenium-debug.log
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+

+ 10 - 0
.postcssrc.js

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

+ 5 - 0
.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js: stable
+script: npm run test
+notifications:
+  email: false

+ 48 - 0
build/build.js

@@ -0,0 +1,48 @@
+'use strict'
+require('./check-versions')()
+
+const ora = require('ora')
+const rm = require('rimraf')
+const path = require('path')
+const chalk = require('chalk')
+const webpack = require('webpack')
+const config = require('../config')
+const webpackConfig = require('./webpack.prod.conf')
+const server = require('pushstate-server')
+
+var spinner = ora('building for '+ process.env.env_config+ ' environment...' )
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+  if (err) throw err
+  webpack(webpackConfig, (err, stats) => {
+    spinner.stop()
+    if (err) throw err
+    process.stdout.write(stats.toString({
+      colors: true,
+      modules: false,
+      children: false,
+      chunks: false,
+      chunkModules: false
+    }) + '\n\n')
+
+    if (stats.hasErrors()) {
+      console.log(chalk.red('  Build failed with errors.\n'))
+      process.exit(1)
+    }
+
+    console.log(chalk.cyan('  Build complete.\n'))
+    console.log(chalk.yellow(
+      '  Tip: built files are meant to be served over an HTTP server.\n' +
+      '  Opening index.html over file:// won\'t work.\n'
+    ))
+    if(process.env.npm_config_preview){
+      server.start({
+          port: 9526,
+          directory: './dist',
+          file: '/index.html'
+      });
+      console.log('> Listening at ' +  'http://localhost:9526' + '\n')
+    }
+  })
+})

+ 54 - 0
build/check-versions.js

@@ -0,0 +1,54 @@
+'use strict'
+const chalk = require('chalk')
+const semver = require('semver')
+const packageConfig = require('../package.json')
+const shell = require('shelljs')
+
+function exec (cmd) {
+  return require('child_process').execSync(cmd).toString().trim()
+}
+
+const versionRequirements = [
+  {
+    name: 'node',
+    currentVersion: semver.clean(process.version),
+    versionRequirement: packageConfig.engines.node
+  }
+]
+
+if (shell.which('npm')) {
+  versionRequirements.push({
+    name: 'npm',
+    currentVersion: exec('npm --version'),
+    versionRequirement: packageConfig.engines.npm
+  })
+}
+
+module.exports = function () {
+  const warnings = []
+
+  for (let i = 0; i < versionRequirements.length; i++) {
+    const mod = versionRequirements[i]
+
+    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
+      warnings.push(mod.name + ': ' +
+        chalk.red(mod.currentVersion) + ' should be ' +
+        chalk.green(mod.versionRequirement)
+      )
+    }
+  }
+
+  if (warnings.length) {
+    console.log('')
+    console.log(chalk.yellow('To use this template, you must update following to modules:'))
+    console.log()
+
+    for (let i = 0; i < warnings.length; i++) {
+      const warning = warnings[i]
+      console.log('  ' + warning)
+    }
+
+    console.log()
+    process.exit(1)
+  }
+}

BIN
build/logo.png


+ 101 - 0
build/utils.js

@@ -0,0 +1,101 @@
+'use strict'
+const path = require('path')
+const config = require('../config')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const packageConfig = require('../package.json')
+
+exports.assetsPath = function (_path) {
+  const assetsSubDirectory = process.env.NODE_ENV === 'production'
+    ? config.build.assetsSubDirectory
+    : config.dev.assetsSubDirectory
+
+  return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function (options) {
+  options = options || {}
+
+  const cssLoader = {
+    loader: 'css-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  const postcssLoader = {
+    loader: 'postcss-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  // generate loader string to be used with extract text plugin
+  function generateLoaders (loader, loaderOptions) {
+    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
+
+    if (loader) {
+      loaders.push({
+        loader: loader + '-loader',
+        options: Object.assign({}, loaderOptions, {
+          sourceMap: options.sourceMap
+        })
+      })
+    }
+
+    // Extract CSS when that option is specified
+    // (which is the case during production build)
+    if (options.extract) {
+      return ExtractTextPlugin.extract({
+        use: loaders,
+        fallback: 'vue-style-loader'
+      })
+    } else {
+      return ['vue-style-loader'].concat(loaders)
+    }
+  }
+
+  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+  return {
+    css: generateLoaders(),
+    postcss: generateLoaders(),
+    less: generateLoaders('less'),
+    sass: generateLoaders('sass', { indentedSyntax: true }),
+    scss: generateLoaders('sass'),
+    stylus: generateLoaders('stylus'),
+    styl: generateLoaders('stylus')
+  }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function (options) {
+  const output = []
+  const loaders = exports.cssLoaders(options)
+
+  for (const extension in loaders) {
+    const loader = loaders[extension]
+    output.push({
+      test: new RegExp('\\.' + extension + '$'),
+      use: loader
+    })
+  }
+
+  return output
+}
+
+exports.createNotifierCallback = () => {
+  const notifier = require('node-notifier')
+
+  return (severity, errors) => {
+    if (severity !== 'error') return
+
+    const error = errors[0]
+    const filename = error.file && error.file.split('!').pop()
+
+    notifier.notify({
+      title: packageConfig.name,
+      message: severity + ': ' + error.name,
+      subtitle: filename || '',
+      icon: path.join(__dirname, 'logo.png')
+    })
+  }
+}

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

@@ -0,0 +1,22 @@
+'use strict'
+const utils = require('./utils')
+const config = require('../config')
+const isProduction = process.env.NODE_ENV === 'production'
+const sourceMapEnabled = isProduction
+  ? config.build.productionSourceMap
+  : config.dev.cssSourceMap
+
+module.exports = {
+  loaders: utils.cssLoaders({
+    sourceMap: sourceMapEnabled,
+    extract: isProduction
+  }),
+  cssSourceMap: sourceMapEnabled,
+  cacheBusting: config.dev.cacheBusting,
+  transformToRequire: {
+    video: ['src', 'poster'],
+    source: 'src',
+    img: 'src',
+    image: 'xlink:href'
+  }
+}

+ 101 - 0
build/webpack.base.conf.js

@@ -0,0 +1,101 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+const vueLoaderConfig = require('./vue-loader.conf')
+
+function resolve (dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const createLintingRule = () => ({
+  test: /\.(js|vue)$/,
+  loader: 'eslint-loader',
+  enforce: 'pre',
+  include: [resolve('src'), resolve('test')],
+  options: {
+    formatter: require('eslint-friendly-formatter'),
+    emitWarning: !config.dev.showEslintErrorsInOverlay
+  }
+})
+
+module.exports = {
+  context: path.resolve(__dirname, '../'),
+  entry: {
+    app: './src/main.js'
+  },
+  output: {
+    path: config.build.assetsRoot,
+    filename: '[name].js',
+    publicPath: process.env.NODE_ENV === 'production'
+      ? config.build.assetsPublicPath
+      : config.dev.assetsPublicPath
+  },
+  resolve: {
+    extensions: ['.js', '.vue', '.json'],
+    alias: {
+      'vue$': 'vue/dist/vue.esm.js',
+      '@': resolve('src'),
+    }
+  },
+  module: {
+    rules: [
+      ...(config.dev.useEslint ? [createLintingRule()] : []),
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: vueLoaderConfig
+      },
+      {
+        test: /\.js$/,
+        loader: 'babel-loader?cacheDirectory',
+        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
+      },
+      {
+        test: /\.svg$/,
+        loader: 'svg-sprite-loader',
+        include: [resolve('src/icons')],
+        options: {
+          symbolId: 'icon-[name]'
+        }
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        loader: 'url-loader',
+        exclude: [resolve('src/icons')],
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+        }
+      }
+    ]
+  },
+  node: {
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
+    // source contains it (although only uses it if it's native).
+    setImmediate: false,
+    // prevent webpack from injecting mocks to Node native modules
+    // that does not make sense for the client
+    dgram: 'empty',
+    fs: 'empty',
+    net: 'empty',
+    tls: 'empty',
+    child_process: 'empty'
+  }
+}

+ 88 - 0
build/webpack.dev.conf.js

@@ -0,0 +1,88 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+function resolve (dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const HOST = process.env.HOST
+const PORT = process.env.PORT && Number(process.env.PORT)
+
+const devWebpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
+  },
+  // cheap-module-eval-source-map is faster for development
+  devtool: config.dev.devtool,
+
+  // these devServer options should be customized in /config/index.js
+  devServer: {
+    clientLogLevel: 'warning',
+    historyApiFallback: true,
+    hot: true,
+    compress: true,
+    host: HOST || config.dev.host,
+    port: PORT || config.dev.port,
+    open: config.dev.autoOpenBrowser,
+    overlay: config.dev.errorOverlay
+      ? { warnings: false, errors: true }
+      : false,
+    publicPath: config.dev.assetsPublicPath,
+    proxy: config.dev.proxyTable,
+    quiet: true, // necessary for FriendlyErrorsPlugin
+    watchOptions: {
+      poll: config.dev.poll,
+    }
+  },
+  plugins: [
+    new webpack.DefinePlugin({
+      'process.env': require('../config/dev.env')
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
+    new webpack.NoEmitOnErrorsPlugin(),
+    // https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'index.html',
+      inject: true,
+      favicon: resolve('favicon.ico'),
+      title: 'zmall-admin',
+      path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
+    }),
+  ]
+})
+
+module.exports = new Promise((resolve, reject) => {
+  portfinder.basePort = process.env.PORT || config.dev.port
+  portfinder.getPort((err, port) => {
+    if (err) {
+      reject(err)
+    } else {
+      // publish the new Port, necessary for e2e tests
+      process.env.PORT = port
+      // add port to devServer config
+      devWebpackConfig.devServer.port = port
+
+      // Add FriendlyErrorsPlugin
+      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
+        compilationSuccessInfo: {
+          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
+        },
+        onErrors: config.dev.notifyOnErrors
+        ? utils.createNotifierCallback()
+        : undefined
+      }))
+
+      resolve(devWebpackConfig)
+    }
+  })
+})

+ 175 - 0
build/webpack.prod.conf.js

@@ -0,0 +1,175 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+
+function resolve (dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const env = require('../config/'+process.env.env_config+'.env')
+
+const webpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.build.productionSourceMap,
+      extract: true,
+      usePostCSS: true
+    })
+  },
+  devtool: config.build.productionSourceMap ? config.build.devtool : false,
+  output: {
+    path: config.build.assetsRoot,
+    filename: utils.assetsPath('js/[name].[chunkhash].js'),
+    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
+  },
+  plugins: [
+    // http://vuejs.github.io/vue-loader/en/workflow/production.html
+    new webpack.DefinePlugin({
+      'process.env': env
+    }),
+    new UglifyJsPlugin({
+      uglifyOptions: {
+        compress: {
+          warnings: false
+        }
+      },
+      sourceMap: config.build.productionSourceMap,
+      parallel: true
+    }),
+    // extract css into its own file
+    new ExtractTextPlugin({
+      filename: utils.assetsPath('css/[name].[contenthash].css'),
+      // Setting the following option to `false` will not extract CSS from codesplit chunks.
+      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
+      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
+      allChunks: false,
+    }),
+    // Compress extracted CSS. We are using this plugin so that possible
+    // duplicated CSS from different components can be deduped.
+    new OptimizeCSSPlugin({
+      cssProcessorOptions: config.build.productionSourceMap
+        ? { safe: true, map: { inline: false } }
+        : { safe: true }
+    }),
+    // generate dist index.html with correct asset hash for caching.
+    // you can customize output by editing /index.html
+    // see https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: config.build.index,
+      template: 'index.html',
+      inject: true,
+      favicon: resolve('favicon.ico'),
+      title: 'vue-element-admin',
+      path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
+      minify: {
+        removeComments: true,
+        collapseWhitespace: true,
+        removeAttributeQuotes: true
+        // more options:
+        // https://github.com/kangax/html-minifier#options-quick-reference
+      },
+      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
+      chunksSortMode: 'dependency'
+    }),
+    // keep module.id stable when vender modules does not change
+    new webpack.HashedModuleIdsPlugin(),
+    // enable scope hoisting
+    new webpack.optimize.ModuleConcatenationPlugin(),
+    // split vendor js into its own file
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'vendor',
+      minChunks (module) {
+        // any required modules inside node_modules are extracted to vendor
+        return (
+          module.resource &&
+          /\.js$/.test(module.resource) &&
+          module.resource.indexOf(
+            path.join(__dirname, '../node_modules')
+          ) === 0
+        )
+      }
+    }),
+    // extract webpack runtime and module manifest to its own file in order to
+    // prevent vendor hash from being updated whenever app bundle is updated
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'manifest',
+      minChunks: Infinity
+    }),
+    // This instance extracts shared chunks from code splitted chunks and bundles them
+    // in a separate chunk, similar to the vendor chunk
+    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'app',
+      async: 'vendor-async',
+      children: true,
+      minChunks: 3
+    }),
+    // split echarts into its own file
+    new webpack.optimize.CommonsChunkPlugin({
+      async: 'echarts',
+      minChunks(module) {
+        var context = module.context;
+        return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
+      }
+    }),
+    // split xlsx into its own file
+    new webpack.optimize.CommonsChunkPlugin({
+      async: 'xlsx',
+      minChunks(module) {
+        var context = module.context;
+        return context && (context.indexOf('xlsx') >= 0);
+      }
+    }),
+     // split codemirror into its own file
+     new webpack.optimize.CommonsChunkPlugin({
+      async: 'codemirror',
+      minChunks(module) {
+        var context = module.context;
+        return context && (context.indexOf('codemirror') >= 0);
+      }
+    }),
+
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.build.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+if (config.build.productionGzip) {
+  const CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+  webpackConfig.plugins.push(
+    new CompressionWebpackPlugin({
+      asset: '[path].gz[query]',
+      algorithm: 'gzip',
+      test: new RegExp(
+        '\\.(' +
+        config.build.productionGzipExtensions.join('|') +
+        ')$'
+      ),
+      threshold: 10240,
+      minRatio: 0.8
+    })
+  )
+}
+
+if (config.build.bundleAnalyzerReport) {
+  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig

+ 9 - 0
config/dev.env.js

@@ -0,0 +1,9 @@
+module.exports = {
+	NODE_ENV: '"development"',
+	ENV_CONFIG: '"dev"',
+  BASE_API: '"https://xiaoyou.dgtis.com/admin"',
+  // OS_API: '"http://10.32.2.208:9081/storage"',
+  // BASE_API: '"http://192.168.100.41:9083/admin"',
+  // 本地数据库:登录用户名 admin123,密码 admin123
+  OS_API: '"https://xiaoyou.dgtis.com/admin"'
+}

+ 83 - 0
config/index.js

@@ -0,0 +1,83 @@
+'use strict'
+// Template version: 1.2.6
+// see http://vuejs-templates.github.io/webpack for documentation.
+
+const path = require('path')
+
+module.exports = {
+  dev: {
+
+    // Paths
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable: {},
+
+    // Various Dev Server settings
+    host: 'localhost', // can be overwritten by process.env.HOST
+    port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
+    autoOpenBrowser: true,
+    errorOverlay: true,
+    notifyOnErrors: false,
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
+
+    // Use Eslint Loader?
+    // If true, your code will be linted during bundling and
+    // linting errors and warnings will be shown in the console.
+    useEslint: false,
+    // If true, eslint errors and warnings will also be shown in the error overlay
+    // in the browser.
+    showEslintErrorsInOverlay: false,
+
+    /**
+     * Source Maps
+     */
+
+    // https://webpack.js.org/configuration/devtool/#development
+    devtool: '#cheap-source-map',
+
+    // If you have problems debugging vue-files in devtools,
+    // set this to false - it *may* help
+    // https://vue-loader.vuejs.org/en/options.html#cachebusting
+    cacheBusting: true,
+
+    // CSS Sourcemaps off by default because relative paths are "buggy"
+    // with this option, according to the CSS-Loader README
+    // (https://github.com/webpack/css-loader#sourcemaps)
+    // In our experience, they generally work as expected,
+    // just be aware of this issue when enabling this option.
+    cssSourceMap: false,
+  },
+
+  build: {
+    // Template for index.html
+    index: path.resolve(__dirname, '../dist/index.html'),
+
+    // Paths
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+
+    // you can set by youself according to actual condition
+    assetsPublicPath: './',
+
+    /**
+     * Source Maps
+     */
+
+    productionSourceMap: false,
+    // https://webpack.js.org/configuration/devtool/#production
+    devtool: '#source-map',
+
+    // Gzip off by default as many popular static hosts such as
+    // Surge or Netlify already gzip all static assets for you.
+    // Before setting to `true`, make sure to:
+    // npm install --save-dev compression-webpack-plugin
+    productionGzip: false,
+    productionGzipExtensions: ['js', 'css'],
+
+    // Run the build command with an extra argument to
+    // View the bundle analyzer report after build finishes:
+    // `npm run build --report`
+    // Set to `true` or `false` to always turn it on or off
+    bundleAnalyzerReport: process.env.npm_config_report
+  }
+}

+ 12 - 0
config/prod.env.js

@@ -0,0 +1,12 @@
+module.exports = {
+	NODE_ENV: '"production"',
+	ENV_CONFIG: '"prod"',
+  //BASE_API: '"http://166.111.100.45/admin"',
+	//清华环境
+  //BASE_API: '"http://alumni.sppm.tsinghua.edu.cn/admin"',
+	//通誉环境
+  //BASE_API: '"http://10.32.2.208:9083/admin"',
+  // OS_API: '"http://10.32.2.208:9081/storage"'
+  BASE_API: '"https://xiaoyou.dgtis.com/admin"',
+  OS_API: '"https://xiaoyou.dgtis.com/admin"'
+}

BIN
favicon.ico


+ 15 - 0
index.html

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+		<meta name="renderer" content="webkit">
+		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+		<title>校友录-后台管理</title>
+	</head>
+	<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.11/tinymce.min.js></script>
+	<body>
+		<div id="app"></div>
+		<!-- built files will be auto injected -->
+	</body>
+</html>

+ 90 - 0
package.json

@@ -0,0 +1,90 @@
+{
+  "name": "alumni-record-admin",
+  "version": "0.1.0",
+  "description": "litemall-admin basing on vue-element-admin 3.6.2",
+  "author": "linlinjava <linlinjava@163.com>",
+  "license": "MIT",
+  "private": true,
+  "scripts": {
+    "dev": "webpack-dev-server --open --inline --progress --config build/webpack.dev.conf.js",
+    "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
+    "lint": "eslint --ext .js,.vue src",
+    "test": "npm run lint"
+  },
+  "dependencies": {
+    "axios": "0.17.1",
+    "clipboard": "1.7.1",
+    "echarts": "3.8.5",
+    "element-ui": "2.0.8",
+    "file-saver": "1.3.3",
+    "font-awesome": "4.7.0",
+    "js-cookie": "2.2.0",
+    "mockjs": "1.0.1-beta3",
+    "normalize.css": "7.0.0",
+    "nprogress": "0.2.0",
+    "screenfull": "3.3.2",
+    "vue": "2.5.10",
+    "vue-count-to": "1.0.13",
+    "vue-router": "3.0.1",
+    "vue-splitpane": "1.0.2",
+    "vuex": "3.0.1",
+    "xlsx": "^0.11.16"
+  },
+  "devDependencies": {
+    "autoprefixer": "7.2.3",
+    "babel-core": "6.26.0",
+    "babel-eslint": "8.0.3",
+    "babel-helper-vue-jsx-merge-props": "2.0.3",
+    "babel-loader": "7.1.2",
+    "babel-plugin-syntax-jsx": "6.18.0",
+    "babel-plugin-transform-runtime": "6.23.0",
+    "babel-plugin-transform-vue-jsx": "3.5.0",
+    "babel-preset-env": "1.6.1",
+    "babel-preset-stage-2": "6.24.1",
+    "chalk": "2.3.0",
+    "copy-webpack-plugin": "4.3.0",
+    "cross-env": "5.1.1",
+    "css-loader": "0.28.7",
+    "eslint": "4.13.1",
+    "eslint-friendly-formatter": "3.0.0",
+    "eslint-loader": "1.9.0",
+    "eslint-plugin-html": "4.0.1",
+    "extract-text-webpack-plugin": "3.0.2",
+    "file-loader": "1.1.5",
+    "friendly-errors-webpack-plugin": "1.6.1",
+    "html-webpack-plugin": "2.30.1",
+    "node-notifier": "5.1.2",
+    "node-sass": "7.0.1",
+    "optimize-css-assets-webpack-plugin": "3.2.0",
+    "ora": "1.3.0",
+    "portfinder": "1.0.13",
+    "postcss-import": "11.0.0",
+    "postcss-loader": "2.0.9",
+    "postcss-url": "7.3.0",
+    "pushstate-server": "3.0.1",
+    "rimraf": "2.6.2",
+    "sass-loader": "6.0.6",
+    "script-loader": "0.7.2",
+    "semver": "5.4.1",
+    "shelljs": "0.7.8",
+    "svg-sprite-loader": "3.5.2",
+    "uglifyjs-webpack-plugin": "1.1.3",
+    "url-loader": "0.6.2",
+    "vue-loader": "13.5.0",
+    "vue-style-loader": "3.0.3",
+    "vue-template-compiler": "2.5.10",
+    "webpack": "3.10.0",
+    "webpack-bundle-analyzer": "2.9.1",
+    "webpack-dev-server": "2.9.7",
+    "webpack-merge": "4.1.1"
+  },
+  "engines": {
+    "node": ">= 4.0.0",
+    "npm": ">= 3.0.0"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ]
+}

+ 29 - 0
src/App.vue

@@ -0,0 +1,29 @@
+<template>
+	<div id="app">
+		<router-view v-if="isRouterAlive"></router-view>
+	</div>
+</template>
+
+<script>
+  export default{
+    name: 'APP',
+    provide (){
+      return {
+        reload: this.reload
+      }
+    },
+    data () {
+      return {
+        isRouterAlive:true
+      }
+    },
+    methods: {
+      reload(){
+        this.isRouterAlive = false
+        this.$nextTick(function () {
+          this.isRouterAlive = true
+        })
+      }
+    }
+  }
+</script>

+ 41 - 0
src/api/activitytag.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function listActivityTag(query) {
+  return request({
+    url: '/tag/list',
+    method: 'get',
+    param: query
+  })
+}
+
+export function createActivityTag(data) {
+  return request({
+    url: '/tag/create',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteActivityTag(data) {
+  return request({
+    url: '/tag/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function ActivityUser(query) {
+  return request({
+    url: '/ActivityUser/listActUser',
+    method: 'post',
+    params: query
+  })
+}
+
+export function ActivityUserAll(query) {
+  return request({
+    url: '/ActivityUser/listActUserAll',
+    method: 'post',
+    params: query
+  })
+}

+ 57 - 0
src/api/admin.js

@@ -0,0 +1,57 @@
+import request from '@/utils/request'
+
+export function listAdmin(query) {
+  return request({
+    url: '/admin/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createAdmin(data) {
+  return request({
+    url: '/admin/create',
+    method: 'post',
+    data
+  })
+}
+
+export function getUser(query) {
+  return request({
+    url: '/admin/getUser',
+    method: 'get',
+    params: query
+  })
+}
+
+export function readminAdmin(data) {
+  return request({
+    url: '/admin/readmin',
+    method: 'get',
+    data
+  })
+}
+
+export function updateAdmin(data) {
+  return request({
+    url: '/admin/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteAdmin(data) {
+  return request({
+    url: '/admin/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function getWxUserId(query) {
+  return request({
+    url: '/admin/getWxUserId',
+    method: 'get',
+    params: query
+  })
+}

+ 10 - 0
src/api/approvehistory.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+/*查询驳回记录列表*/
+export function listApproveHistory(query) {
+  return request({
+    url:'/approveHistory/list',
+    method:'get',
+    params:query
+  })
+}

+ 41 - 0
src/api/banner.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function listBanner(query) {
+  return request({
+    url: '/banner/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createBanner(data) {
+  return request({
+    url: '/banner/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readBanner(data) {
+  return request({
+    url: '/banner/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateBanner(data) {
+  return request({
+    url: '/banner/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteBanner(data) {
+  return request({
+    url: '/banner/delete',
+    method: 'post',
+    data
+  })
+}

+ 9 - 0
src/api/dashboard.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function info(query) {
+  return request({
+    url: '/dashboard',
+    method: 'get',
+    params: query
+  })
+}

+ 37 - 0
src/api/login.js

@@ -0,0 +1,37 @@
+import request from '@/utils/request'
+
+export function loginByUsername(username, password) {
+  const data = {
+    username,
+    password
+  }
+  return request({
+    url: '/login/login',
+    method: 'post',
+    data
+  })
+}
+
+export function logout() {
+  return request({
+    url: '/login/logout',
+    method: 'post'
+  })
+}
+
+export function getUserInfo(token) {
+  return request({
+    url: '/admin/info',
+    method: 'get',
+    params: { token }
+  })
+}
+
+export function getUserMenu(token) {
+  return request({
+    url: '/role/selectAdminMenu',
+    method: 'post',
+    params: { token }
+  })
+}
+

+ 87 - 0
src/api/news.js

@@ -0,0 +1,87 @@
+import request from '@/utils/request'
+
+export function listNews(query) {
+  return request({
+    url: '/news/list',
+    method: 'post',
+    data: query
+  })
+}
+
+export function createNews(data) {
+  return request({
+    url: '/news/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readNews(data) {
+  return request({
+    url: '/news/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateNews(data) {
+  return request({
+    url: '/news/update',
+    method: 'post',
+    data
+  })
+}
+
+export function updateNewsAuth(data) {
+  return request({
+    url: '/news/updateNewsAuth',
+    method: 'post',
+    data
+  })
+}
+
+
+export function deleteNews(data) {
+  return request({
+    url: '/news/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteAllNews(data) {
+  return request({
+    url: '/news/deleteQuantity',
+    method: 'post',
+    params: data
+  })
+}
+
+export function listActivityOrg(data) {
+  return request({
+    url: '/news/listActivityOrg',
+    method: 'get',
+    params: data
+  })
+}
+export function listCommon(data) {
+  return request({
+    url: '/newsComment/listCommon',
+    method: 'get',
+    params: data
+  })
+}
+export function deleteCommon(data) {
+  return request({
+    url: '/newsComment/deleteCommon',
+    method: 'post',
+    data
+  })
+}
+  export function deleteAllConent(data) {
+    return request({
+      url: '/newsComment/deleteQuantity',
+      method: 'post',
+      params: data
+    })
+}

+ 49 - 0
src/api/newsCenter.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function getdgtIndustryNews(query) {
+  return request({
+    url: '/news/getdgtIndustryNews',
+    method: 'post',
+    data: query
+  })
+}
+
+export function listNews(query) {
+  return request({
+    url: '/news/listForDGTSiteNews',
+    method: 'post',
+    data: query
+  })
+}
+
+export function createNews(data) {
+  return request({
+    url: '/news/createForDGTSiteNews',
+    method: 'post',
+    data
+  })
+}
+
+export function updateNews(data) {
+  return request({
+    url: '/news/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteNews(data) {
+  return request({
+    url: '/news/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteAllNews(data) {
+  return request({
+    url: '/news/deleteQuantity',
+    method: 'post',
+    params: data
+  })
+}

+ 75 - 0
src/api/organize.js

@@ -0,0 +1,75 @@
+import request from '@/utils/request'
+
+export function selectOrg(query) {
+  return request({
+    url: '/organize/selectOrganize',
+    method: 'post',
+    params: query
+  })
+}
+
+
+export function createOrg(query) {
+  return request({
+    url: '/organize/createOrganize',
+    method: 'post',
+    params: query
+  })
+}
+
+export function updateOrg(query) {
+  return request({
+    url: '/organize/updateOrganize',
+    method: 'post',
+    params: query
+  })
+}
+
+export function updateOrgAuth(data) {
+  return request({
+    url: '/organize/updateOrgAuth',
+    method: 'post',
+    data
+  })
+}
+
+export function sendWXMsg(query) {
+  return request({
+    url: '/organize/sendWXMsg',
+    method: 'post',
+    params: query
+  })
+}
+
+export function deleteOrg(data) {
+  return request({
+    url: '/organize/deleteOrgById',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteOrgList(query) {
+  return request({
+    url: '/organize/deleteOrgQuantity',
+    method: 'post',
+    params: query
+  })
+}
+
+export function auditOrganizeInterest(query) {
+  return request({
+    url: '/organize/auditOrganizeInterest',
+    method: 'post',
+    params: query
+  })
+}
+
+
+export function selectUserByUserName(query) {
+  return request({
+    url: '/organize/selectUserByUserName',
+    method: 'post',
+    params: query
+  })
+}

+ 36 - 0
src/api/organizeuser.js

@@ -0,0 +1,36 @@
+import request from '@/utils/request'
+
+export function selectOrganizeUserByOrgId(query) {
+  return request({
+    url: '/organizeuser/selectOrganizeUserByOrgId',
+    method: 'post',
+    params: query
+  })
+}
+
+export function selectOrganizeUserByOrgIdNoDel(query) {
+  return request({
+    url: '/organizeuser/selectOrganizeUserByOrgIdNoDel',
+    method: 'post',
+    params: query
+  })
+}
+
+
+export function updateOrganizeUserById(query) {
+  return request({
+    url: '/organizeuser/updateOrganizeUserById',
+    method: 'post',
+    params: query
+  })
+}
+
+
+
+export function sendWXMsg(query) {
+  return request({
+    url: '/organizeuser/sendWXMsg',
+    method: 'post',
+    params: query
+  })
+}

+ 41 - 0
src/api/questionDetail.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function listQuestionDetail(query) {
+  return request({
+    url: '/questionDetail/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createQuestionDetail(data) {
+  return request({
+    url: '/questionDetail/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readQuestionDetail(data) {
+  return request({
+    url: '/questionDetail/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateQuestionDetail(data) {
+  return request({
+    url: '/questionDetail/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteQuestionDetail(data) {
+  return request({
+    url: '/questionDetail/delete',
+    method: 'post',
+    data
+  })
+}

+ 41 - 0
src/api/questionSort.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function listQuestionSort(query) {
+  return request({
+    url: '/questionSort/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createQuestionSort(data) {
+  return request({
+    url: '/questionSort/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readQuestionSort(data) {
+  return request({
+    url: '/questionSort/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateQuestionSort(data) {
+  return request({
+    url: '/questionSort/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteQuestionSort(data) {
+  return request({
+    url: '/questionSort/delete',
+    method: 'post',
+    data
+  })
+}

+ 50 - 0
src/api/questions.js

@@ -0,0 +1,50 @@
+import request from '@/utils/request'
+
+export function listBanner(query) {
+  return request({
+    url: '/questions/list',
+    method: 'get',
+    params: query
+  })
+}
+
+
+export function createBanner(data) {
+  return request({
+    url: '/questions/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readBanner(data) {
+  return request({
+    url: '/questions/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateBanner(data) {
+  return request({
+    url: '/questions/update',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteBanner(data) {
+  return request({
+    url: '/questions/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function createContribute(data) {
+  return request({
+    url: '/contribute/create',
+    method: 'post',
+    data
+  })
+}

+ 73 - 0
src/api/role.js

@@ -0,0 +1,73 @@
+import request from '@/utils/request'
+
+/* 权限添加 */
+export function updateRoleMenu(query) {
+  return request({
+    url: '/role/insertRoleMenu',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 查询权限 */
+export function getRoleMenu(query) {
+  return request({
+    url: '/role/selectMenuByRoleId',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 添加角色 */
+export function addRole(query) {
+  return request({
+    url: '/role/insertSelective',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 修改角色名称 */
+export function updateRoleName(query) {
+  return request({
+    url: '/role/updateByPrimaryKeySelective',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 角色列表 */
+export function roleList(query) {
+  return request({
+    url: '/role/selectByRoleName',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 查询用户拥有的角色 */
+export function selectAdminRole(query) {
+  return request({
+    url: '/role/selectAdminRole',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 添加用户与角色关联 */
+export function addAdminRole(query) {
+  return request({
+    url: '/role/insertAdminRole',
+    method: 'post',
+    params: query
+  })
+}
+
+/* 查询当前用户权限列表 */
+// export function addAdminRole(data) {
+//   return request({
+//     url: 'role/selectAdminMenu',
+//     method: 'post',
+//     data
+//   })
+// }

+ 71 - 0
src/api/storage.js

@@ -0,0 +1,71 @@
+import axios from 'axios'
+
+// create an axios instance
+const service = axios.create({
+  // baseURL: process.env.OS_API, // api的base_url
+  baseURL: process.env.BASE_API,
+  timeout: 10000 // request timeout
+})
+
+const myService = axios.create({
+  baseURL: process.env.OS_API, // api的base_url
+  // baseURL: process.env.BASE_API,
+  timeout: 10000 // request timeout
+})
+
+/*批量导入员工福利信息 excel*/
+export function insetListWelfare(data) {
+  return service({
+    url: '/welfare/insertList',
+    method: 'post',
+    data
+  })
+}
+
+export function listStorage(query) {
+  return service({
+    url: '/storage/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createStorage(data) {
+  return service({
+    url: '/storage/create',
+    method: 'post',
+    data
+  })
+}
+export function uploadPic(data) {
+  return myService({
+    url: '/storage/uploadPic',
+    method: 'post',
+    data
+  })
+}
+
+export function readStorage(data) {
+  return service({
+    url: '/storage/read',
+    method: 'get',
+    data
+  })
+}
+
+export function updateStorage(data) {
+  return service({
+    url: '/storage/update',
+    method: 'post',
+    params: data
+  })
+}
+
+export function deleteStorage(data) {
+  debugger;
+  return service({
+    url: '/storage/delete',
+    method: 'post',
+    params: data
+  })
+}

+ 17 - 0
src/api/trend.js

@@ -0,0 +1,17 @@
+import request from '@/utils/request'
+
+export function listTrend(query) {
+  return request({
+    url: '/news/listTidings',
+    method: 'post',
+    params: query
+  })
+}
+
+export function deleteTrend(data) {
+  return request({
+    url: '/news/delete',
+    method: 'post',
+    data
+  })
+}

+ 108 - 0
src/api/user.js

@@ -0,0 +1,108 @@
+import request from '@/utils/request'
+
+/*查询校友录列表*/
+export function fetchList(query) {
+  return request({
+    url: '/user/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function exportAllUser(query) {
+  return request({
+    url: '/user/exportAllUser',
+    method: 'get',
+    params: query
+  })
+}
+
+/*查询游客列表*/
+export function fetYKList(query) {
+  return request({
+    url:'/user/findYKList',
+    method:'get',
+    params:query
+  })
+
+}
+
+export function fetchCheckUserList(query) {
+  return request({
+    url: '/user/searchAwaitAuditUserList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createUser(data) {
+  return request({
+    url: '/user/create',
+    method: 'post',
+    data
+  })
+}
+
+export function readUser(data) {
+  return request({
+    url: '/user/detail',
+    method: 'get',
+    params: data
+  })
+}
+
+export function updateUser(data) {
+  return request({
+    url: '/user/update',
+    method: 'post',
+    data
+  })
+}
+
+export function auditUser(data) {
+  return request({
+    url: '/user/auditUser',
+    method: 'post',
+    data
+  })
+}
+
+export function getUserRole(data) {
+  return request({
+    url: '/role/selectAdminRole',
+    method: 'post',
+    data
+  })
+}
+
+export function passUserAudit(data) {
+  return request({
+    url: '/user/passAudit',
+    method: 'post',
+    params: data
+  })
+}
+
+export function getConcernedList(data) {
+  return request({
+    url: '/user/findUserConcerned',
+    method: 'post',
+    data
+  })
+}
+
+export function getMessageUser(data) {
+  return request({
+    url: '/message/list',
+    method: 'post',
+    params: data
+  })
+}
+
+export function getOrganizeList(data) {
+  return request({
+    url: '/user/findMyOrganize',
+    method: 'post',
+    params: data
+  })
+}

+ 25 - 0
src/api/visitor.js

@@ -0,0 +1,25 @@
+import request from '@/utils/request'
+/*查询访客列表*/
+export function fetchList(query) {
+  return request({
+    url: '/alumniVisitor/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function deleteVisitor(data) {
+  return request({
+    url: '/alumniVisitor/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function uploadVisitor(data) {
+  return request({
+    url: '/alumniVisitor/upload',
+    method: 'post',
+    data
+  })
+}

+ 26 - 0
src/api/welfare.js

@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+
+export function listWelfare(query) {
+  return request({
+    url: '/welfare/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function updateWelfare(data) {
+  return request({
+    url: '/welfare/update',
+    method: 'post',
+    data
+  })
+}
+
+
+export function deleteWelfare(data) {
+  return request({
+    url: '/welfare/delete',
+    method: 'post',
+    data
+  })
+}

BIN
src/assets/401_images/401.gif


BIN
src/assets/404_images/404.png


BIN
src/assets/404_images/404_cloud.png


+ 199 - 0
src/assets/echarts-macarons.js

@@ -0,0 +1,199 @@
+/* eslint-disable */
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define(['exports', 'echarts'], factory);
+    } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
+        // CommonJS
+        factory(exports, require('echarts'));
+    } else {
+        // Browser globals
+        factory({}, root.echarts);
+    }
+}(this, function (exports, echarts) {
+    var log = function (msg) {
+        if (typeof console !== 'undefined') {
+            console && console.error && console.error(msg);
+        }
+    };
+    if (!echarts) {
+        log('ECharts is not Loaded');
+        return;
+    }
+
+    var colorPalette = [
+        '#2ec7c9','#b6a2de','#5ab1ef','#ffb980','#d87a80',
+        '#8d98b3','#e5cf0d','#97b552','#95706d','#dc69aa',
+        '#07a2a4','#9a7fd1','#588dd5','#f5994e','#c05050',
+        '#59678c','#c9ab00','#7eb00a','#6f5553','#c14089'
+    ];
+
+
+    var theme = {
+        color: colorPalette,
+
+        title: {
+            textStyle: {
+                fontWeight: 'normal',
+                color: '#008acd'
+            }
+        },
+
+        visualMap: {
+            itemWidth: 15,
+            color: ['#5ab1ef','#e0ffff']
+        },
+
+        toolbox: {
+            iconStyle: {
+                normal: {
+                    borderColor: colorPalette[0]
+                }
+            }
+        },
+
+        tooltip: {
+            backgroundColor: 'rgba(50,50,50,0.5)',
+            axisPointer : {
+                type : 'line',
+                lineStyle : {
+                    color: '#008acd'
+                },
+                crossStyle: {
+                    color: '#008acd'
+                },
+                shadowStyle : {
+                    color: 'rgba(200,200,200,0.2)'
+                }
+            }
+        },
+
+        dataZoom: {
+            dataBackgroundColor: '#efefff',
+            fillerColor: 'rgba(182,162,222,0.2)',
+            handleColor: '#008acd'
+        },
+
+        grid: {
+            borderColor: '#eee'
+        },
+
+        categoryAxis: {
+            axisLine: {
+                lineStyle: {
+                    color: '#008acd'
+                }
+            },
+            splitLine: {
+                lineStyle: {
+                    color: ['#eee']
+                }
+            }
+        },
+
+        valueAxis: {
+            axisLine: {
+                lineStyle: {
+                    color: '#008acd'
+                }
+            },
+            splitArea : {
+                show : true,
+                areaStyle : {
+                    color: ['rgba(250,250,250,0.1)','rgba(200,200,200,0.1)']
+                }
+            },
+            splitLine: {
+                lineStyle: {
+                    color: ['#eee']
+                }
+            }
+        },
+
+        timeline : {
+            lineStyle : {
+                color : '#008acd'
+            },
+            controlStyle : {
+                normal : { color : '#008acd'},
+                emphasis : { color : '#008acd'}
+            },
+            symbol : 'emptyCircle',
+            symbolSize : 3
+        },
+
+        line: {
+            smooth : true,
+            symbol: 'emptyCircle',
+            symbolSize: 3
+        },
+
+        candlestick: {
+            itemStyle: {
+                normal: {
+                    color: '#d87a80',
+                    color0: '#2ec7c9',
+                    lineStyle: {
+                        color: '#d87a80',
+                        color0: '#2ec7c9'
+                    }
+                }
+            }
+        },
+
+        scatter: {
+            symbol: 'circle',
+            symbolSize: 4
+        },
+
+        map: {
+            label: {
+                normal: {
+                    textStyle: {
+                        color: '#d87a80'
+                    }
+                }
+            },
+            itemStyle: {
+                normal: {
+                    borderColor: '#eee',
+                    areaColor: '#ddd'
+                },
+                emphasis: {
+                    areaColor: '#fe994e'
+                }
+            }
+        },
+
+        graph: {
+            color: colorPalette
+        },
+
+        gauge : {
+            axisLine: {
+                lineStyle: {
+                    color: [[0.2, '#2ec7c9'],[0.8, '#5ab1ef'],[1, '#d87a80']],
+                    width: 10
+                }
+            },
+            axisTick: {
+                splitNumber: 10,
+                length :15,
+                lineStyle: {
+                    color: 'auto'
+                }
+            },
+            splitLine: {
+                length :22,
+                lineStyle: {
+                    color: 'auto'
+                }
+            },
+            pointer : {
+                width : 5
+            }
+        }
+    };
+
+    echarts.registerTheme('macarons', theme);
+}));

+ 112 - 0
src/components/BackToTop/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <transition :name="transitionName">
+    <div class="back-to-ceiling" @click="backToTop" v-show="visible" :style="customStyle">
+      <svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height: 16px; width: 16px;">
+        <title>回到顶部</title>
+        <g>
+          <path d="M12.036 15.59c0 .55-.453.995-.997.995H5.032c-.55 0-.997-.445-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29c.39-.39 1.026-.385 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" fill-rule="evenodd"></path>
+        </g>
+      </svg>
+    </div>
+  </transition>
+</template>
+
+<script>
+export default {
+  name: 'BackToTop',
+  props: {
+    visibilityHeight: {
+      type: Number,
+      default: 400
+    },
+    backPosition: {
+      type: Number,
+      default: 0
+    },
+    customStyle: {
+      type: Object,
+      default: function() {
+        return {
+          right: '50px',
+          bottom: '50px',
+          width: '40px',
+          height: '40px',
+          'border-radius': '4px',
+          'line-height': '45px',
+          background: '#e7eaf1'
+        }
+      }
+    },
+    transitionName: {
+      type: String,
+      default: 'fade'
+    }
+  },
+  data() {
+    return {
+      visible: false,
+      interval: null
+    }
+  },
+  mounted() {
+    window.addEventListener('scroll', this.handleScroll)
+  },
+  beforeDestroy() {
+    window.removeEventListener('scroll', this.handleScroll)
+    if (this.interval) {
+      clearInterval(this.interval)
+    }
+  },
+  methods: {
+    handleScroll() {
+      this.visible = window.pageYOffset > this.visibilityHeight
+    },
+    backToTop() {
+      const start = window.pageYOffset
+      let i = 0
+      this.interval = setInterval(() => {
+        const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500))
+        if (next <= this.backPosition) {
+          window.scrollTo(0, this.backPosition)
+          clearInterval(this.interval)
+        } else {
+          window.scrollTo(0, next)
+        }
+        i++
+      }, 16.7)
+    },
+    easeInOutQuad(t, b, c, d) {
+      if ((t /= d / 2) < 1) return c / 2 * t * t + b
+      return -c / 2 * (--t * (t - 2) - 1) + b
+    }
+  }
+}
+</script>
+
+<style scoped>
+  .back-to-ceiling {
+    position: fixed;
+    display: inline-block;
+    text-align: center;
+    cursor: pointer;
+  }
+
+  .back-to-ceiling:hover {
+    background: #d5dbe7;
+  }
+
+  .fade-enter-active,
+  .fade-leave-active {
+    transition: opacity .5s;
+  }
+
+  .fade-enter,
+  .fade-leave-to {
+    opacity: 0
+  }
+
+  .back-to-ceiling .Icon {
+    fill: #9aaabf;
+    background: none;
+  }
+</style>

+ 52 - 0
src/components/Breadcrumb/index.vue

@@ -0,0 +1,52 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index)  in levelList" :key="item.path" v-if='item.meta.title'>
+        <span v-if='item.redirect==="noredirect"||index==levelList.length-1' class="no-redirect">{{item.meta.title}}</span>
+        <router-link v-else :to="item.redirect||item.path">{{item.meta.title}}</router-link>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+
+export default {
+  created() {
+    this.getBreadcrumb()
+  },
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route() {
+      this.getBreadcrumb()
+    }
+  },
+  methods: {
+    getBreadcrumb() {
+      let matched = this.$route.matched.filter(item => item.name)
+      const first = matched[0]
+      if (first && first.name !== 'dashboard') {
+        matched = [{ path: '/dashboard', meta: { title: '主页' }}].concat(matched)
+      }
+      this.levelList = matched
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+  .app-breadcrumb.el-breadcrumb {
+    display: inline-block;
+    font-size: 14px;
+    line-height: 50px;
+    margin-left: 10px;
+    .no-redirect {
+      color: #97a8be;
+      cursor: text;
+    }
+  }
+</style>

+ 150 - 0
src/components/Charts/keyboard.vue

@@ -0,0 +1,150 @@
+<template>
+  <div :class="className" :id="id" :style="{height:height,width:width}"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+
+export default {
+  props: {
+    className: {
+      type: String,
+      default: 'chart'
+    },
+    id: {
+      type: String,
+      default: 'chart'
+    },
+    width: {
+      type: String,
+      default: '200px'
+    },
+    height: {
+      type: String,
+      default: '200px'
+    }
+  },
+  data() {
+    return {
+      chart: null
+    }
+  },
+  mounted() {
+    this.initChart()
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return
+    }
+    this.chart.dispose()
+    this.chart = null
+  },
+  methods: {
+    initChart() {
+      this.chart = echarts.init(document.getElementById(this.id))
+
+      const xAxisData = []
+      const data = []
+      const data2 = []
+      for (let i = 0; i < 50; i++) {
+        xAxisData.push(i)
+        data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
+        data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
+      }
+      this.chart.setOption(
+        {
+          backgroundColor: '#08263a',
+          xAxis: [{
+            show: false,
+            data: xAxisData
+          }, {
+            show: false,
+            data: xAxisData
+          }],
+          visualMap: {
+            show: false,
+            min: 0,
+            max: 50,
+            dimension: 0,
+            inRange: {
+              color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
+            }
+          },
+          yAxis: {
+            axisLine: {
+              show: false
+            },
+            axisLabel: {
+              textStyle: {
+                color: '#4a657a'
+              }
+            },
+            splitLine: {
+              show: true,
+              lineStyle: {
+                color: '#08263f'
+              }
+            },
+            axisTick: {
+              show: false
+            }
+          },
+          series: [{
+            name: 'back',
+            type: 'bar',
+            data: data2,
+            z: 1,
+            itemStyle: {
+              normal: {
+                opacity: 0.4,
+                barBorderRadius: 5,
+                shadowBlur: 3,
+                shadowColor: '#111'
+              }
+            }
+          }, {
+            name: 'Simulate Shadow',
+            type: 'line',
+            data,
+            z: 2,
+            showSymbol: false,
+            animationDelay: 0,
+            animationEasing: 'linear',
+            animationDuration: 1200,
+            lineStyle: {
+              normal: {
+                color: 'transparent'
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: '#08263a',
+                shadowBlur: 50,
+                shadowColor: '#000'
+              }
+            }
+          }, {
+            name: 'front',
+            type: 'bar',
+            data,
+            xAxisIndex: 1,
+            z: 3,
+            itemStyle: {
+              normal: {
+                barBorderRadius: 5
+              }
+            }
+          }],
+          animationEasing: 'elasticOut',
+          animationEasingUpdate: 'elasticOut',
+          animationDelay(idx) {
+            return idx * 20
+          },
+          animationDelayUpdate(idx) {
+            return idx * 20
+          }
+        })
+    }
+  }
+}
+</script>

+ 225 - 0
src/components/Charts/lineMarker.vue

@@ -0,0 +1,225 @@
+<template>
+  <div :class="className" :id="id" :style="{height:height,width:width}"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+
+export default {
+  props: {
+    className: {
+      type: String,
+      default: 'chart'
+    },
+    id: {
+      type: String,
+      default: 'chart'
+    },
+    width: {
+      type: String,
+      default: '200px'
+    },
+    height: {
+      type: String,
+      default: '200px'
+    }
+  },
+  data() {
+    return {
+      chart: null
+    }
+  },
+  mounted() {
+    this.initChart()
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return
+    }
+    this.chart.dispose()
+    this.chart = null
+  },
+  methods: {
+    initChart() {
+      this.chart = echarts.init(document.getElementById(this.id))
+
+      this.chart.setOption({
+        backgroundColor: '#394056',
+        title: {
+          top: 20,
+          text: 'Requests',
+          textStyle: {
+            fontWeight: 'normal',
+            fontSize: 16,
+            color: '#F1F1F3'
+          },
+          left: '1%'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          }
+        },
+        legend: {
+          top: 20,
+          icon: 'rect',
+          itemWidth: 14,
+          itemHeight: 5,
+          itemGap: 13,
+          data: ['CMCC', 'CTCC', 'CUCC'],
+          right: '4%',
+          textStyle: {
+            fontSize: 12,
+            color: '#F1F1F3'
+          }
+        },
+        grid: {
+          top: 100,
+          left: '3%',
+          right: '4%',
+          bottom: '2%',
+          containLabel: true
+        },
+        xAxis: [{
+          type: 'category',
+          boundaryGap: false,
+          axisLine: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          },
+          data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
+        }],
+        yAxis: [{
+          type: 'value',
+          name: '(%)',
+          axisTick: {
+            show: false
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          },
+          axisLabel: {
+            margin: 10,
+            textStyle: {
+              fontSize: 14
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          }
+        }],
+        series: [{
+          name: 'CMCC',
+          type: 'line',
+          smooth: true,
+          symbol: 'circle',
+          symbolSize: 5,
+          showSymbol: false,
+          lineStyle: {
+            normal: {
+              width: 1
+            }
+          },
+          areaStyle: {
+            normal: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                offset: 0,
+                color: 'rgba(137, 189, 27, 0.3)'
+              }, {
+                offset: 0.8,
+                color: 'rgba(137, 189, 27, 0)'
+              }], false),
+              shadowColor: 'rgba(0, 0, 0, 0.1)',
+              shadowBlur: 10
+            }
+          },
+          itemStyle: {
+            normal: {
+              color: 'rgb(137,189,27)',
+              borderColor: 'rgba(137,189,2,0.27)',
+              borderWidth: 12
+
+            }
+          },
+          data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
+        }, {
+          name: 'CTCC',
+          type: 'line',
+          smooth: true,
+          symbol: 'circle',
+          symbolSize: 5,
+          showSymbol: false,
+          lineStyle: {
+            normal: {
+              width: 1
+            }
+          },
+          areaStyle: {
+            normal: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                offset: 0,
+                color: 'rgba(0, 136, 212, 0.3)'
+              }, {
+                offset: 0.8,
+                color: 'rgba(0, 136, 212, 0)'
+              }], false),
+              shadowColor: 'rgba(0, 0, 0, 0.1)',
+              shadowBlur: 10
+            }
+          },
+          itemStyle: {
+            normal: {
+              color: 'rgb(0,136,212)',
+              borderColor: 'rgba(0,136,212,0.2)',
+              borderWidth: 12
+
+            }
+          },
+          data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
+        }, {
+          name: 'CUCC',
+          type: 'line',
+          smooth: true,
+          symbol: 'circle',
+          symbolSize: 5,
+          showSymbol: false,
+          lineStyle: {
+            normal: {
+              width: 1
+            }
+          },
+          areaStyle: {
+            normal: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                offset: 0,
+                color: 'rgba(219, 50, 51, 0.3)'
+              }, {
+                offset: 0.8,
+                color: 'rgba(219, 50, 51, 0)'
+              }], false),
+              shadowColor: 'rgba(0, 0, 0, 0.1)',
+              shadowBlur: 10
+            }
+          },
+          itemStyle: {
+            normal: {
+              color: 'rgb(219,50,51)',
+              borderColor: 'rgba(219,50,51,0.2)',
+              borderWidth: 12
+            }
+          },
+          data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
+        }]
+      })
+    }
+  }
+}
+</script>

+ 268 - 0
src/components/Charts/mixChart.vue

@@ -0,0 +1,268 @@
+<template>
+  <div :class="className" :id="id" :style="{height:height,width:width}"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+
+export default {
+  props: {
+    className: {
+      type: String,
+      default: 'chart'
+    },
+    id: {
+      type: String,
+      default: 'chart'
+    },
+    width: {
+      type: String,
+      default: '200px'
+    },
+    height: {
+      type: String,
+      default: '200px'
+    }
+  },
+  data() {
+    return {
+      chart: null
+    }
+  },
+  mounted() {
+    this.initChart()
+    this.chart = null
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return
+    }
+    this.chart.dispose()
+    this.chart = null
+  },
+  methods: {
+    initChart() {
+      this.chart = echarts.init(document.getElementById(this.id))
+      const xData = (function() {
+        const data = []
+        for (let i = 1; i < 13; i++) {
+          data.push(i + 'month')
+        }
+        return data
+      }())
+      this.chart.setOption({
+        backgroundColor: '#344b58',
+        title: {
+          text: 'statistics',
+          x: '20',
+          top: '20',
+          textStyle: {
+            color: '#fff',
+            fontSize: '22'
+          },
+          subtextStyle: {
+            color: '#90979c',
+            fontSize: '16'
+          }
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            textStyle: {
+              color: '#fff'
+            }
+          }
+        },
+        grid: {
+          borderWidth: 0,
+          top: 110,
+          bottom: 95,
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        legend: {
+          x: '5%',
+          top: '10%',
+          textStyle: {
+            color: '#90979c'
+          },
+          data: ['female', 'male', 'average']
+        },
+        calculable: true,
+        xAxis: [{
+          type: 'category',
+          axisLine: {
+            lineStyle: {
+              color: '#90979c'
+            }
+          },
+          splitLine: {
+            show: false
+          },
+          axisTick: {
+            show: false
+          },
+          splitArea: {
+            show: false
+          },
+          axisLabel: {
+            interval: 0
+
+          },
+          data: xData
+        }],
+        yAxis: [{
+          type: 'value',
+          splitLine: {
+            show: false
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#90979c'
+            }
+          },
+          axisTick: {
+            show: false
+          },
+          axisLabel: {
+            interval: 0
+          },
+          splitArea: {
+            show: false
+          }
+        }],
+        dataZoom: [{
+          show: true,
+          height: 30,
+          xAxisIndex: [
+            0
+          ],
+          bottom: 30,
+          start: 10,
+          end: 80,
+          handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
+          handleSize: '110%',
+          handleStyle: {
+            color: '#d3dee5'
+
+          },
+          textStyle: {
+            color: '#fff' },
+          borderColor: '#90979c'
+
+        }, {
+          type: 'inside',
+          show: true,
+          height: 15,
+          start: 1,
+          end: 35
+        }],
+        series: [{
+          name: 'female',
+          type: 'bar',
+          stack: 'total',
+          barMaxWidth: 35,
+          barGap: '10%',
+          itemStyle: {
+            normal: {
+              color: 'rgba(255,144,128,1)',
+              label: {
+                show: true,
+                textStyle: {
+                  color: '#fff'
+                },
+                position: 'insideTop',
+                formatter(p) {
+                  return p.value > 0 ? p.value : ''
+                }
+              }
+            }
+          },
+          data: [
+            709,
+            1917,
+            2455,
+            2610,
+            1719,
+            1433,
+            1544,
+            3285,
+            5208,
+            3372,
+            2484,
+            4078
+          ]
+        },
+
+        {
+          name: 'male',
+          type: 'bar',
+          stack: 'total',
+          itemStyle: {
+            normal: {
+              color: 'rgba(0,191,183,1)',
+              barBorderRadius: 0,
+              label: {
+                show: true,
+                position: 'top',
+                formatter(p) {
+                  return p.value > 0 ? p.value : ''
+                }
+              }
+            }
+          },
+          data: [
+            327,
+            1776,
+            507,
+            1200,
+            800,
+            482,
+            204,
+            1390,
+            1001,
+            951,
+            381,
+            220
+          ]
+        }, {
+          name: 'average',
+          type: 'line',
+          stack: 'total',
+          symbolSize: 10,
+          symbol: 'circle',
+          itemStyle: {
+            normal: {
+              color: 'rgba(252,230,48,1)',
+              barBorderRadius: 0,
+              label: {
+                show: true,
+                position: 'top',
+                formatter(p) {
+                  return p.value > 0 ? p.value : ''
+                }
+              }
+            }
+          },
+          data: [
+            1036,
+            3693,
+            2962,
+            3810,
+            2519,
+            1915,
+            1748,
+            4675,
+            6209,
+            4323,
+            2865,
+            4298
+          ]
+        }
+        ]
+      })
+    }
+  }
+}
+</script>

+ 45 - 0
src/components/Hamburger/index.vue

@@ -0,0 +1,45 @@
+<template>
+  <div>
+    <svg t="1492500959545" @click="toggleClick" class="wscn-icon hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
+      version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
+      <path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
+        p-id="1692"></path>
+      <path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
+        p-id="1693"></path>
+      <path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
+        p-id="1694"></path>
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    },
+    toggleClick: {
+      type: Function,
+      default: null
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+	display: inline-block;
+	cursor: pointer;
+	width: 20px;
+	height: 20px;
+	transform: rotate(90deg);
+	transition: .38s;
+	transform-origin: 50% 50%;
+}
+
+.hamburger.is-active {
+	transform: rotate(0deg);
+}
+</style>

+ 65 - 0
src/components/Screenfull/index.vue

@@ -0,0 +1,65 @@
+<template>
+  <div>
+    <svg t="1508738709248" @click='click' class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+      p-id="2069" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32">
+      <path d="M333.493443 428.647617 428.322206 333.832158 262.572184 168.045297 366.707916 64.444754 64.09683 64.444754 63.853283 366.570793 167.283957 262.460644Z"
+        p-id="2070"></path>
+      <path d="M854.845439 760.133334 688.61037 593.95864 593.805144 688.764889 759.554142 854.56096 655.44604 958.161503 958.055079 958.161503 958.274066 656.035464Z"
+        p-id="2071"></path>
+      <path d="M688.535669 428.550403 854.31025 262.801405 957.935352 366.921787 957.935352 64.34754 655.809313 64.081481 759.919463 167.535691 593.70793 333.731874Z"
+        p-id="2072"></path>
+      <path d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z"
+        p-id="2073"></path>
+    </svg>
+  </div>
+</template>
+
+<script>
+import screenfull from 'screenfull'
+
+export default {
+  name: 'screenfull',
+  props: {
+    width: {
+      type: Number,
+      default: 22
+    },
+    height: {
+      type: Number,
+      default: 22
+    },
+    fill: {
+      type: String,
+      default: '#48576a'
+    }
+  },
+  data() {
+    return {
+      isFullscreen: false
+    }
+  },
+  methods: {
+    click() {
+      if (!screenfull.enabled) {
+        this.$message({
+          message: 'you browser can not work',
+          type: 'warning'
+        })
+        return false
+      }
+      screenfull.toggle()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.screenfull-svg {
+  display: inline-block;
+  cursor: pointer;
+  fill: #5a5e66;;
+  width: 20px;
+  height: 20px;
+  vertical-align: 10px;
+}
+</style>

+ 57 - 0
src/components/ScrollBar/index.vue

@@ -0,0 +1,57 @@
+<template>
+  <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll" >
+    <div class="scroll-wrapper" ref="scrollWrapper" :style="{top: top + 'px'}">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+const delta = 15
+
+export default {
+  name: 'scrollBar',
+  data() {
+    return {
+      top: 0
+    }
+  },
+  methods: {
+    handleScroll(e) {
+      const eventDelta = e.wheelDelta || -e.deltaY * 3
+      const $container = this.$refs.scrollContainer
+      const $containerHeight = $container.offsetHeight
+      const $wrapper = this.$refs.scrollWrapper
+      const $wrapperHeight = $wrapper.offsetHeight
+      if (eventDelta > 0) {
+        this.top = Math.min(0, this.top + eventDelta)
+      } else {
+        if ($containerHeight - delta < $wrapperHeight) {
+          if (this.top < -($wrapperHeight - $containerHeight + delta)) {
+            this.top = this.top
+          } else {
+            this.top = Math.max(this.top + eventDelta, $containerHeight - $wrapperHeight - delta)
+          }
+        } else {
+          this.top = 0
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+@import '../../styles/variables.scss';
+
+.scroll-container {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background-color: $menuBg;
+  .scroll-wrapper {
+    position: absolute;
+     width: 100%!important;
+  }
+}
+</style>

+ 72 - 0
src/components/ScrollPane/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll">
+    <div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+const padding = 15 // tag's padding
+
+export default {
+  name: 'scrollPane',
+  data() {
+    return {
+      left: 0
+    }
+  },
+  methods: {
+    handleScroll(e) {
+      const eventDelta = e.wheelDelta || -e.deltaY * 3
+      const $container = this.$refs.scrollContainer
+      const $containerWidth = $container.offsetWidth
+      const $wrapper = this.$refs.scrollWrapper
+      const $wrapperWidth = $wrapper.offsetWidth
+
+      if (eventDelta > 0) {
+        this.left = Math.min(0, this.left + eventDelta)
+      } else {
+        if ($containerWidth - padding < $wrapperWidth) {
+          if (this.left < -($wrapperWidth - $containerWidth + padding)) {
+            this.left = this.left
+          } else {
+            this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding)
+          }
+        } else {
+          this.left = 0
+        }
+      }
+    },
+    moveToTarget($target) {
+      const $container = this.$refs.scrollContainer
+      const $containerWidth = $container.offsetWidth
+      const $targetLeft = $target.offsetLeft
+      const $targetWidth = $target.offsetWidth
+
+      if ($targetLeft < -this.left) {
+        // tag in the left
+        this.left = -$targetLeft + padding
+      } else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) {
+        // tag in the current view
+        // eslint-disable-line
+      } else {
+        // tag in the right
+        this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding)
+      }
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.scroll-container {
+  white-space: nowrap;
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  .scroll-wrapper {
+    position: absolute;
+  }
+}
+</style>

+ 76 - 0
src/components/Sticky/index.vue

@@ -0,0 +1,76 @@
+<template>
+  <div :style="{height:height+'px',zIndex:zIndex}">
+    <div :class="className" :style="{top:stickyTop+'px',zIndex:zIndex,position:position,width:width,height:height+'px'}">
+      <slot>
+        <div>sticky</div>
+      </slot>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Sticky',
+  props: {
+    stickyTop: {
+      type: Number,
+      default: 0
+    },
+    zIndex: {
+      type: Number,
+      default: 1
+    },
+    className: {
+      type: String
+    }
+  },
+  data() {
+    return {
+      active: false,
+      position: '',
+      currentTop: '',
+      width: undefined,
+      height: undefined,
+      child: null,
+      stickyHeight: 0
+    }
+  },
+  mounted() {
+    this.height = this.$el.getBoundingClientRect().height
+    window.addEventListener('scroll', this.handleScroll)
+  },
+  activated() {
+    this.handleScroll()
+  },
+  destroyed() {
+    window.removeEventListener('scroll', this.handleScroll)
+  },
+  methods: {
+    sticky() {
+      if (this.active) {
+        return
+      }
+      this.position = 'fixed'
+      this.active = true
+      this.width = this.width + 'px'
+    },
+    reset() {
+      if (!this.active) {
+        return
+      }
+      this.position = ''
+      this.width = 'auto'
+      this.active = false
+    },
+    handleScroll() {
+      this.width = this.$el.getBoundingClientRect().width
+      const offsetTop = this.$el.getBoundingClientRect().top
+      if (offsetTop <= this.stickyTop) {
+        this.sticky()
+        return
+      }
+      this.reset()
+    }
+  }
+}
+</script>

+ 42 - 0
src/components/SvgIcon/index.vue

@@ -0,0 +1,42 @@
+<template>
+  <svg :class="svgClass" aria-hidden="true">
+    <use :xlink:href="iconName"></use>
+  </svg>
+</template>
+
+<script>
+export default {
+  name: 'svg-icon',
+  props: {
+    iconClass: {
+      type: String,
+      required: true
+    },
+    className: {
+      type: String
+    }
+  },
+  computed: {
+    iconName() {
+      return `#icon-${this.iconClass}`
+    },
+    svgClass() {
+      if (this.className) {
+        return 'svg-icon ' + this.className
+      } else {
+        return 'svg-icon'
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>

+ 181 - 0
src/components/Tinymce/index.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="tinymce-container editor-container">
+    <textarea class="tinymce-textarea" :id="tinymceId"></textarea>
+  </div>
+</template>
+
+<script>
+import plugins from './plugins'
+import toolbar from './toolbar'
+import { uploadPic } from '@/api/storage'
+
+export default {
+  name: 'tinymce',
+  props: {
+    id: {
+      type: String
+    },
+    value: {
+      type: String,
+      default: ''
+    },
+    toolbar: {
+      type: Array,
+      required: false,
+      default() {
+        return []
+      }
+    },
+    menubar: {
+      default: 'file edit insert view format table'
+    },
+    height: {
+      type: Number,
+      required: false,
+      default: 360
+    }
+  },
+  data() {
+    return {
+      hasChange: false,
+      hasInit: false,
+      tinymceId: this.id || 'vue-tinymce-' + +new Date()
+    }
+  },
+  watch: {
+    value(val) {
+      if (!this.hasChange && this.hasInit) {
+        this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val))
+      }
+    }
+  },
+  mounted() {
+    this.initTinymce()
+  },
+  activated() {
+    this.initTinymce()
+  },
+  deactivated() {
+    this.destroyTinymce()
+  },
+  methods: {
+    initTinymce() {
+      const _this = this
+      window.tinymce.init({
+        selector: `#${this.tinymceId}`,
+        height: this.height,
+        language: 'zh_CN',
+        body_class: 'panel-body ',
+        object_resizing: false,
+        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
+        menubar: this.menubar,
+        plugins: plugins,
+        end_container_on_empty_block: true,
+        powerpaste_word_import: 'clean',
+        code_dialog_height: 450,
+        code_dialog_width: 1000,
+        advlist_bullet_styles: 'square',
+        advlist_number_styles: 'default',
+        default_link_target: '_blank',
+        relative_urls : false,
+		remove_script_host : false,
+		document_base_url : 'http://xiaoyou.dgtis.com/',
+        link_title: false,
+        init_instance_callback: editor => {
+          if (_this.value) {
+            editor.setContent(_this.value)
+          }
+          _this.hasInit = true
+          editor.on('NodeChange Change KeyUp', () => {
+            this.hasChange = true
+            this.$emit('input', editor.getContent({ format: 'raw' }))
+          })
+        },
+        images_upload_handler: function(blobInfo, success, failure) {
+          const formData = new FormData()
+          formData.append('file', blobInfo.blob())
+          uploadPic(formData).then(res => {
+          var resurl=res.data.data.url;
+          console.log(resurl);
+            success(resurl)
+          }).catch(() => {
+            failure('上传失败,请重新上传')
+          })
+        }
+        // 整合七牛上传
+        // images_dataimg_filter(img) {
+        //   setTimeout(() => {
+        //     const $image = $(img);
+        //     $image.removeAttr('width');
+        //     $image.removeAttr('height');
+        //     if ($image[0].height && $image[0].width) {
+        //       $image.attr('data-wscntype', 'image');
+        //       $image.attr('data-wscnh', $image[0].height);
+        //       $image.attr('data-wscnw', $image[0].width);
+        //       $image.addClass('wscnph');
+        //     }
+        //   }, 0);
+        //   return img
+        // },
+        // images_upload_handler(blobInfo, success, failure, progress) {
+        //   progress(0);
+        //   const token = _this.$store.getters.token;
+        //   getToken(token).then(response => {
+        //     const url = response.data.qiniu_url;
+        //     const formData = new FormData();
+        //     formData.append('token', response.data.qiniu_token);
+        //     formData.append('key', response.data.qiniu_key);
+        //     formData.append('file', blobInfo.blob(), url);
+        //     upload(formData).then(() => {
+        //       success(url);
+        //       progress(100);
+        //     })
+        //   }).catch(err => {
+        //     failure('出现未知问题,刷新页面,或者联系程序员')
+        //     console.log(err);
+        //   });
+        // },
+      })
+    },
+    destroyTinymce() {
+      if (window.tinymce.get(this.tinymceId)) {
+        window.tinymce.get(this.tinymceId).destroy()
+      }
+    },
+    setContent(value) {
+      window.tinymce.get(this.tinymceId).setContent(value)
+    },
+    getContent() {
+      window.tinymce.get(this.tinymceId).getContent()
+    },
+    imageSuccessCBK(arr) {
+      const _this = this
+      arr.forEach(v => {
+        window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
+      })
+    }
+  },
+  destroyed() {
+    this.destroyTinymce()
+  }
+}
+</script>
+
+<style scoped>
+.tinymce-container {
+  position: relative
+}
+.tinymce-textarea {
+  visibility: hidden;
+  z-index: -1;
+}
+.editor-custom-btn-container {
+  position: absolute;
+  right: 4px;
+  top: 4px;
+  /*z-index: 2005;*/
+}
+.editor-upload-btn {
+  display: inline-block;
+}
+</style>

+ 7 - 0
src/components/Tinymce/plugins.js

@@ -0,0 +1,7 @@
+// Any plugins you want to use has to be imported
+// Detail plugins list see https://www.tinymce.com/docs/plugins/
+// Custom builds see https://www.tinymce.com/download/custom-builds/
+
+const plugins = ['advlist anchor autolink autoresize autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
+
+export default plugins

+ 6 - 0
src/components/Tinymce/toolbar.js

@@ -0,0 +1,6 @@
+// Here is a list of the toolbar
+// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
+
+const toolbar = ['bold italic underline strikethrough alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap	 preview anchor pagebreak fullscreen insertdatetime media table emoticons forecolor backcolor']
+
+export default toolbar

+ 123 - 0
src/components/Upload/singleImage.vue

@@ -0,0 +1,123 @@
+<template>
+    <div class="upload-container">
+        <el-upload class="image-uploader" :data="dataObj" drag :multiple="false" :show-file-list="false" action="https://httpbin.org/post"
+            :on-success="handleImageScucess">
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        </el-upload>
+        <div class="image-preview">
+            <div class="image-preview-wrapper" v-show="imageUrl.length>1">
+                <img :src="imageUrl+'?imageView2/1/w/200/h/200'">
+                <div class="image-preview-action">
+                    <i @click="rmImage" class="el-icon-delete"></i>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+// 预览效果见付费文章
+import { getToken } from '@/api/qiniu'
+
+export default {
+  name: 'singleImageUpload',
+  props: {
+    value: String
+  },
+  computed: {
+    imageUrl() {
+      return this.value
+    }
+  },
+  data() {
+    return {
+      tempUrl: '',
+      dataObj: { token: '', key: '' }
+    }
+  },
+  methods: {
+    rmImage() {
+      this.emitInput('')
+    },
+    emitInput(val) {
+      this.$emit('input', val)
+    },
+    handleImageScucess() {
+      this.emitInput(this.tempUrl)
+    },
+    beforeUpload() {
+      const _self = this
+      return new Promise((resolve, reject) => {
+        getToken().then(response => {
+          const key = response.data.qiniu_key
+          const token = response.data.qiniu_token
+          _self._data.dataObj.token = token
+          _self._data.dataObj.key = key
+          this.tempUrl = response.data.qiniu_url
+          resolve(true)
+        }).catch(err => {
+          console.log(err)
+          reject(false)
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+    @import "src/styles/mixin.scss";
+    .upload-container {
+        width: 100%;
+        position: relative;
+        @include clearfix;
+        .image-uploader {
+            width: 60%;
+            float: left;
+        }
+        .image-preview {
+            width: 200px;
+            height: 200px;
+            position: relative;
+            border: 1px dashed #d9d9d9;
+            float: left;
+            margin-left: 50px;
+            .image-preview-wrapper {
+                position: relative;
+                width: 100%;
+                height: 100%;
+                img {
+                    width: 100%;
+                    height: 100%;
+                }
+            }
+            .image-preview-action {
+                position: absolute;
+                width: 100%;
+                height: 100%;
+                left: 0;
+                top: 0;
+                cursor: default;
+                text-align: center;
+                color: #fff;
+                opacity: 0;
+                font-size: 20px;
+                background-color: rgba(0, 0, 0, .5);
+                transition: opacity .3s;
+                cursor: pointer;
+                text-align: center;
+                line-height: 200px;
+                .el-icon-delete {
+                    font-size: 36px;
+                }
+            }
+            &:hover {
+                .image-preview-action {
+                    opacity: 1;
+                }
+            }
+        }
+    }
+
+</style>

+ 118 - 0
src/components/Upload/singleImage2.vue

@@ -0,0 +1,118 @@
+<template>
+	<div class="singleImageUpload2 upload-container">
+		<el-upload class="image-uploader" :data="dataObj" drag :multiple="false" :show-file-list="false" action="https://httpbin.org/post"
+		  :on-success="handleImageScucess">
+			<i class="el-icon-upload"></i>
+			<div class="el-upload__text">Drag或<em>点击上传</em></div>
+		</el-upload>
+		<div v-show="imageUrl.length>0" class="image-preview">
+			<div class="image-preview-wrapper" v-show="imageUrl.length>1">
+				<img :src="imageUrl">
+				<div class="image-preview-action">
+					<i @click="rmImage" class="el-icon-delete"></i>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import { getToken } from '@/api/qiniu'
+
+export default {
+  name: 'singleImageUpload2',
+  props: {
+    value: String
+  },
+  computed: {
+    imageUrl() {
+      return this.value
+    }
+  },
+  data() {
+    return {
+      tempUrl: '',
+      dataObj: { token: '', key: '' }
+    }
+  },
+  methods: {
+    rmImage() {
+      this.emitInput('')
+    },
+    emitInput(val) {
+      this.$emit('input', val)
+    },
+    handleImageScucess() {
+      this.emitInput(this.tempUrl)
+    },
+    beforeUpload() {
+      const _self = this
+      return new Promise((resolve, reject) => {
+        getToken().then(response => {
+          const key = response.data.qiniu_key
+          const token = response.data.qiniu_token
+          _self._data.dataObj.token = token
+          _self._data.dataObj.key = key
+          this.tempUrl = response.data.qiniu_url
+          resolve(true)
+        }).catch(() => {
+          reject(false)
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.upload-container {
+	width: 100%;
+	height: 100%;
+	position: relative;
+	.image-uploader {
+		height: 100%;
+	}
+	.image-preview {
+		width: 100%;
+		height: 100%;
+		position: absolute;
+		left: 0px;
+		top: 0px;
+		border: 1px dashed #d9d9d9;
+		.image-preview-wrapper {
+			position: relative;
+			width: 100%;
+			height: 100%;
+			img {
+				width: 100%;
+				height: 100%;
+			}
+		}
+		.image-preview-action {
+			position: absolute;
+			width: 100%;
+			height: 100%;
+			left: 0;
+			top: 0;
+			cursor: default;
+			text-align: center;
+			color: #fff;
+			opacity: 0;
+			font-size: 20px;
+			background-color: rgba(0, 0, 0, .5);
+			transition: opacity .3s;
+			cursor: pointer;
+			text-align: center;
+			line-height: 200px;
+			.el-icon-delete {
+				font-size: 36px;
+			}
+		}
+		&:hover {
+			.image-preview-action {
+				opacity: 1;
+			}
+		}
+	}
+}
+</style>

+ 145 - 0
src/components/Upload/singleImage3.vue

@@ -0,0 +1,145 @@
+<template>
+	<div class="upload-container">
+		<el-upload class="image-uploader" :data="dataObj" drag :multiple="false" :show-file-list="false" action="https://httpbin.org/post"
+		  :on-success="handleImageScucess">
+			<i class="el-icon-upload"></i>
+			<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+		</el-upload>
+		<div class="image-preview image-app-preview">
+			<div class="image-preview-wrapper" v-show="imageUrl.length>1">
+				<img :src="imageUrl">
+				<div class="image-preview-action">
+					<i @click="rmImage" class="el-icon-delete"></i>
+				</div>
+			</div>
+		</div>
+		<div class="image-preview">
+			<div class="image-preview-wrapper" v-show="imageUrl.length>1">
+				<img :src="imageUrl">
+				<div class="image-preview-action">
+					<i @click="rmImage" class="el-icon-delete"></i>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import { getToken } from '@/api/qiniu'
+
+export default {
+  name: 'singleImageUpload3',
+  props: {
+    value: String
+  },
+  computed: {
+    imageUrl() {
+      return this.value
+    }
+  },
+  data() {
+    return {
+      tempUrl: '',
+      dataObj: { token: '', key: '' }
+    }
+  },
+  methods: {
+    rmImage() {
+      this.emitInput('')
+    },
+    emitInput(val) {
+      this.$emit('input', val)
+    },
+    handleImageScucess(file) {
+      this.emitInput(file.files.file)
+    },
+    beforeUpload() {
+      const _self = this
+      return new Promise((resolve, reject) => {
+        getToken().then(response => {
+          const key = response.data.qiniu_key
+          const token = response.data.qiniu_token
+          _self._data.dataObj.token = token
+          _self._data.dataObj.key = key
+          this.tempUrl = response.data.qiniu_url
+          resolve(true)
+        }).catch(err => {
+          console.log(err)
+          reject(false)
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+@import "src/styles/mixin.scss";
+.upload-container {
+	width: 100%;
+	position: relative;
+	@include clearfix;
+	.image-uploader {
+		width: 35%;
+		float: left;
+	}
+	.image-preview {
+		width: 200px;
+		height: 200px;
+		position: relative;
+		border: 1px dashed #d9d9d9;
+		float: left;
+		margin-left: 50px;
+		.image-preview-wrapper {
+			position: relative;
+			width: 100%;
+			height: 100%;
+			img {
+				width: 100%;
+				height: 100%;
+			}
+		}
+		.image-preview-action {
+			position: absolute;
+			width: 100%;
+			height: 100%;
+			left: 0;
+			top: 0;
+			cursor: default;
+			text-align: center;
+			color: #fff;
+			opacity: 0;
+			font-size: 20px;
+			background-color: rgba(0, 0, 0, .5);
+			transition: opacity .3s;
+			cursor: pointer;
+			text-align: center;
+			line-height: 200px;
+			.el-icon-delete {
+				font-size: 36px;
+			}
+		}
+		&:hover {
+			.image-preview-action {
+				opacity: 1;
+			}
+		}
+	}
+	.image-app-preview {
+		width: 320px;
+		height: 180px;
+		position: relative;
+		border: 1px dashed #d9d9d9;
+		float: left;
+		margin-left: 50px;
+		.app-fake-conver {
+			height: 44px;
+			position: absolute;
+			width: 100%; // background: rgba(0, 0, 0, .1);
+			text-align: center;
+			line-height: 64px;
+			color: #fff;
+		}
+	}
+}
+</style>

+ 91 - 0
src/directive/sticky.js

@@ -0,0 +1,91 @@
+const vueSticky = {}
+let listenAction
+vueSticky.install = Vue => {
+  Vue.directive('sticky', {
+    inserted(el, binding) {
+      const params = binding.value || {}
+      const stickyTop = params.stickyTop || 0
+      const zIndex = params.zIndex || 1000
+      const elStyle = el.style
+
+      elStyle.position = '-webkit-sticky'
+      elStyle.position = 'sticky'
+      // if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
+      // if (~elStyle.position.indexOf('sticky')) {
+      //     elStyle.top = `${stickyTop}px`;
+      //     elStyle.zIndex = zIndex;
+      //     return
+      // }
+      const elHeight = el.getBoundingClientRect().height
+      const elWidth = el.getBoundingClientRect().width
+      elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
+
+      const parentElm = el.parentNode || document.documentElement
+      const placeholder = document.createElement('div')
+      placeholder.style.display = 'none'
+      placeholder.style.width = `${elWidth}px`
+      placeholder.style.height = `${elHeight}px`
+      parentElm.insertBefore(placeholder, el)
+
+      let active = false
+
+      const getScroll = (target, top) => {
+        const prop = top ? 'pageYOffset' : 'pageXOffset'
+        const method = top ? 'scrollTop' : 'scrollLeft'
+        let ret = target[prop]
+        if (typeof ret !== 'number') {
+          ret = window.document.documentElement[method]
+        }
+        return ret
+      }
+
+      const sticky = () => {
+        if (active) {
+          return
+        }
+        if (!elStyle.height) {
+          elStyle.height = `${el.offsetHeight}px`
+        }
+
+        elStyle.position = 'fixed'
+        elStyle.width = `${elWidth}px`
+        placeholder.style.display = 'inline-block'
+        active = true
+      }
+
+      const reset = () => {
+        if (!active) {
+          return
+        }
+
+        elStyle.position = ''
+        placeholder.style.display = 'none'
+        active = false
+      }
+
+      const check = () => {
+        const scrollTop = getScroll(window, true)
+        const offsetTop = el.getBoundingClientRect().top
+        if (offsetTop < stickyTop) {
+          sticky()
+        } else {
+          if (scrollTop < elHeight + stickyTop) {
+            reset()
+          }
+        }
+      }
+      listenAction = () => {
+        check()
+      }
+
+      window.addEventListener('scroll', listenAction)
+    },
+
+    unbind() {
+      window.removeEventListener('scroll', listenAction)
+    }
+  })
+}
+
+export default vueSticky
+

+ 13 - 0
src/directive/waves/index.js

@@ -0,0 +1,13 @@
+import waves from './waves'
+
+const install = function(Vue) {
+  Vue.directive('waves', waves)
+}
+
+if (window.Vue) {
+  window.waves = waves
+  Vue.use(install); // eslint-disable-line
+}
+
+waves.install = install
+export default waves

+ 26 - 0
src/directive/waves/waves.css

@@ -0,0 +1,26 @@
+.waves-ripple {
+    position: absolute;
+    border-radius: 100%;
+    background-color: rgba(0, 0, 0, 0.15);
+    background-clip: padding-box;
+    pointer-events: none;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    -webkit-transform: scale(0);
+    -ms-transform: scale(0);
+    transform: scale(0);
+    opacity: 1;
+}
+
+.waves-ripple.z-active {
+    opacity: 0;
+    -webkit-transform: scale(2);
+    -ms-transform: scale(2);
+    transform: scale(2);
+    -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
+    transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
+    transition: opacity 1.2s ease-out, transform 0.6s ease-out;
+    transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
+}

+ 42 - 0
src/directive/waves/waves.js

@@ -0,0 +1,42 @@
+import './waves.css'
+
+export default{
+  bind(el, binding) {
+    el.addEventListener('click', e => {
+      const customOpts = Object.assign({}, binding.value)
+      const opts = Object.assign({
+        ele: el, // 波纹作用元素
+        type: 'hit', // hit点击位置扩散center中心点扩展
+        color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
+      }, customOpts)
+      const target = opts.ele
+      if (target) {
+        target.style.position = 'relative'
+        target.style.overflow = 'hidden'
+        const rect = target.getBoundingClientRect()
+        let ripple = target.querySelector('.waves-ripple')
+        if (!ripple) {
+          ripple = document.createElement('span')
+          ripple.className = 'waves-ripple'
+          ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
+          target.appendChild(ripple)
+        } else {
+          ripple.className = 'waves-ripple'
+        }
+        switch (opts.type) {
+          case 'center':
+            ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
+            ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
+            break
+          default:
+            ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'
+            ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'
+        }
+        ripple.style.backgroundColor = opts.color
+        ripple.className = 'waves-ripple z-active'
+        return false
+      }
+    }, false)
+  }
+}
+

+ 9 - 0
src/icons/index.js

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

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/404.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/bug.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/chart.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/clipboard.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/component.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/dashboard.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/documentation.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/drag.svg


+ 43 - 0
src/icons/svg/edit.svg

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 469.331 469.331" style="enable-background:new 0 0 469.331 469.331;" xml:space="preserve">
+<g>
+	<path d="M438.931,30.403c-40.4-40.5-106.1-40.5-146.5,0l-268.6,268.5c-2.1,2.1-3.4,4.8-3.8,7.7l-19.9,147.4
+		c-0.6,4.2,0.9,8.4,3.8,11.3c2.5,2.5,6,4,9.5,4c0.6,0,1.2,0,1.8-0.1l88.8-12c7.4-1,12.6-7.8,11.6-15.2c-1-7.4-7.8-12.6-15.2-11.6
+		l-71.2,9.6l13.9-102.8l108.2,108.2c2.5,2.5,6,4,9.5,4s7-1.4,9.5-4l268.6-268.5c19.6-19.6,30.4-45.6,30.4-73.3
+		S458.531,49.903,438.931,30.403z M297.631,63.403l45.1,45.1l-245.1,245.1l-45.1-45.1L297.631,63.403z M160.931,416.803l-44.1-44.1
+		l245.1-245.1l44.1,44.1L160.931,416.803z M424.831,152.403l-107.9-107.9c13.7-11.3,30.8-17.5,48.8-17.5c20.5,0,39.7,8,54.2,22.4
+		s22.4,33.7,22.4,54.2C442.331,121.703,436.131,138.703,424.831,152.403z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/email.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/example.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/excel.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/eye.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/form.svg


+ 72 - 0
src/icons/svg/group.svg

@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 487 487" style="enable-background:new 0 0 487 487;" xml:space="preserve">
+<g>
+	<g>
+		<path d="M171.1,260.8c2.9-11.2,8.8-21.5,17.3-30.6c-14.2-9.2-26.1-21.8-34.3-36.6h27.1c3.6,11.6,8.2,21.8,13.2,30.7
+			c3.5-3.2,7.3-6.1,11.3-8.6c1.9-1.3,3.8-2.5,5.7-3.6c-3.1-5.6-5.9-11.8-8.4-18.5h30.6v10.9c1.8-0.3,3.6-0.5,5.4-0.5
+			c2.1-0.2,4.2-0.3,6.2-0.3c3.1,0,6.1,0.2,9,0.6v-10.6h30.7c-2.3,6.5-5.1,12.5-8,17.9c0.6,0.3,1.1,0.6,1.7,0.9
+			c6.6,3.7,11.5,8,14.9,11.7c5-8.9,9.6-19.1,13.1-30.6h27.1c-8,14.4-19.3,26.6-33,35.7c2.7,2,5.3,4.4,7.7,7.4
+			c4.9,6.2,8.1,14,9.7,23.3c38.3-24.5,63.7-67.4,63.7-116.1C381.8,67.9,320,6,243.9,6C167.9,6,106,67.8,106,143.9
+			C106,193.1,132.1,236.5,171.1,260.8z M342.4,114.7c2.7,9.2,4.2,19,4.2,29.1s-1.5,19.9-4.2,29.1h-30.9c1.5-9.1,2.4-18.7,2.4-29.1
+			s-0.9-20.1-2.4-29.1C311.5,114.7,342.4,114.7,342.4,114.7z M333.8,94h-27.1c-5.6-18.1-13.7-32.9-22.1-44.6
+			C305.5,58.5,322.8,74.3,333.8,94z M254.2,45.6c10,10.1,22.4,26,30.6,48.5h-30.6V45.6z M254.2,114.7h36.2
+			c1.7,8.9,2.8,18.6,2.8,29.1s-1,20.2-2.7,29.1h-36.3V114.7z M233.6,173h-36.2c-1.7-8.9-2.8-18.6-2.8-29.1s1-20.2,2.7-29.1h36.3V173
+			z M233.6,94h-30.7c8.1-22.6,20.7-38.6,30.7-48.6V94z M203.2,49.5c-8.4,11.7-16.5,26.5-22.1,44.6H154
+			C165,74.3,182.3,58.5,203.2,49.5z M141.1,143.8c0-10.1,1.5-19.9,4.2-29.1h30.9c-1.5,9.1-2.4,18.7-2.4,29.1s0.9,20.1,2.4,29.1
+			h-30.9C142.6,163.7,141.1,153.9,141.1,143.8z"/>
+		<path d="M463.2,412c-23-8.8-36.7-17.7-36.7-17.7l-17.7,56l-2.4,7.6l-7.9-22.5c18.2-25.4-1.4-26.6-4.8-26.6l0,0c0,0,0,0-0.1,0
+			c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0l0,0c-3.4,0-23,1.2-4.8,26.6l-7.9,22.5l-2.4-7.6l-17.7-56c0,0-7.7,5-21.3,11.3
+			c-3.4-2.6-7.5-4.8-12.5-6.7c-27.3-10.4-43.7-21.1-43.7-21.1l-21.1,66.6l-2.9,9l-9.4-26.7c21.7-30.2-1.6-31.7-5.7-31.7l0,0
+			c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0l0,0c-4,0-27.4,1.5-5.7,31.7l-9.4,26.7l-2.9-9l-21.1-66.6
+			c0,0-16.4,10.7-43.7,21.1c-5,1.8-9.1,4-12.5,6.7c-13.6-6.2-21.3-11.3-21.3-11.3l-17.7,56l-2.4,7.6l-7.9-22.5
+			c18.2-25.4-1.4-26.6-4.8-26.6l0,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0s0,0-0.1,0l0,0c-3.4,0-23,1.2-4.8,26.6L81,457.9
+			l-2.4-7.6l-17.7-56c0,0-13.8,9-36.7,17.7C-1.1,421.2,0.5,442,0,481h89.1h4.8h37.8h56h50.1h5.8h55.6h56h33.2h4.8H487
+			C486.9,442,488.5,421.2,463.2,412z"/>
+		<path d="M381,266.7c-3.8,1.3-7.3,3.2-10.5,5.4c-3.9,2.5-7.5,5.5-10.8,8.9c-5.1,5.2-9.7,12-11.6,20.4c-1.7,6.3-1.3,12.9,0.1,19.9
+			l0,0c0.4,2.1,0.9,4.1,1.7,6.2c-3.9-0.4-8.4,1.9-4.1,17c3.1,11.1,6,14.2,8.2,14.3c2,13.2,12.2,29.9,28.8,35.7
+			c6.8,2.4,14.3,2.4,21.2,0c16.4-5.9,26.9-22.6,28.9-35.7c2.2-0.2,5.1-3.3,8.2-14.3c4.3-15.1-0.3-17.4-4.1-17
+			c0.7-2.1,1.3-4.2,1.7-6.2c6.5-39.2-12.8-40.5-12.8-40.5s-3.2-6.1-11.6-10.8c-5.6-3.3-13.5-5.9-23.9-5
+			C387.2,265,384,265.6,381,266.7L381,266.7z"/>
+		<path d="M54.8,358.8c2,13.2,12.2,29.9,28.8,35.7c6.8,2.4,14.3,2.4,21.2,0c16.4-5.9,26.9-22.6,28.9-35.7c2.2-0.2,5.1-3.3,8.2-14.3
+			c4.3-15.1-0.3-17.4-4.1-17c0.7-2.1,1.3-4.2,1.7-6.2c6.5-39.2-12.8-40.5-12.8-40.5s-3.2-6.1-11.6-10.8c-5.6-3.3-13.5-5.9-23.9-5
+			c-3.4,0.2-6.5,0.8-9.5,1.8l0,0c-3.8,1.3-7.3,3.2-10.4,5.4c-3.9,2.5-7.5,5.5-10.8,8.9c-5.1,5.2-9.7,12-11.6,20.4
+			c-1.7,6.3-1.3,12.9,0.1,19.9l0,0c0.4,2.1,0.9,4.1,1.7,6.2c-3.8-0.4-8.4,1.9-4.1,17C49.7,355.5,52.6,358.6,54.8,358.8z"/>
+		<path d="M187.1,318.4c3.7,13.2,7.2,16.8,9.8,17.1c2.4,15.7,14.5,35.6,34.3,42.5c8.1,2.9,17.1,2.9,25.2-0.1
+			c19.5-7,32-26.9,34.4-42.5c2.6-0.2,6.1-3.9,9.8-17.1c5.1-18-0.3-20.7-4.9-20.2c0.9-2.5,1.5-5,2-7.4c7.8-46.6-15.2-48.2-15.2-48.2
+			s-3.8-7.3-13.8-12.9c-6.7-4-16.1-7.1-28.4-6c-4,0.2-7.8,1-11.3,2.2l0,0c-4.5,1.5-8.7,3.8-12.4,6.4c-4.6,2.9-9,6.5-12.8,10.6
+			c-6.1,6.2-11.5,14.2-13.8,24.3c-2,7.5-1.5,15.3,0.1,23.7l0,0c0.4,2.5,1.1,4.9,2,7.4C187.4,297.8,182,300.4,187.1,318.4z"/>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/icon.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/international.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/language.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/lock.svg


+ 52 - 0
src/icons/svg/magnifying-glass.svg

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 480.925 480.925" style="enable-background:new 0 0 480.925 480.925;" xml:space="preserve">
+<g>
+	<g>
+		<path d="M469.675,415.325l-100.2-100.2l-7.2,7.2l-11.1-11.1c56.9-76.3,50.8-184.8-18.5-254.1c-76.2-76.1-199.5-76.1-275.6,0
+			s-76.1,199.5,0,275.5c69.3,69.3,177.8,75.5,254.1,18.5l11.1,11.1l-7.2,7.2l100.2,100.2c15,15,39.4,15,54.4,0
+			C484.675,454.725,484.675,430.425,469.675,415.325z M290.275,290.325c-52.7,52.7-138.2,52.7-190.9,0s-52.7-138.2,0-190.9
+			s138.2-52.7,190.9,0S342.975,237.625,290.275,290.325z"/>
+		<path d="M155.675,186.225c2,12.9,12,29.4,28.4,35.2c6.7,2.4,14.1,2.4,20.8,0c16.1-5.8,26.4-22.2,28.4-35.1c2.2-0.2,5-3.2,8.1-14.1
+			c4.2-14.9-0.3-17.1-4-16.7c0.7-2.1,1.3-4.1,1.6-6.1c6.4-38.5-12.6-39.9-12.6-39.9s-3.1-6-11.4-10.6c-5.5-3.3-13.3-5.8-23.5-5
+			c-3.3,0.2-6.4,0.8-9.3,1.8l0,0c-3.7,1.3-7.2,3.1-10.3,5.3c-3.8,2.4-7.4,5.4-10.6,8.7c-5,5.1-9.5,11.8-11.4,20.1
+			c-1.6,6.2-1.3,12.6,0.1,19.6l0,0c0.4,2,0.9,4.1,1.6,6.1c-3.8-0.4-8.3,1.8-4,16.7C150.675,183.025,153.575,186.125,155.675,186.225
+			z"/>
+		<path d="M263.375,238.625c-22.6-8.6-36.1-17.5-36.1-17.5l-17.4,55l-2.4,7.5l-7.8-22.1c17.9-25-1.4-26.2-4.7-26.2l0,0
+			c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0s0,0-0.1,0l0,0c-3.3,0-22.6,1.2-4.7,26.2l-7.8,22.1l-2.4-7.5l-17.4-55
+			c0,0-13.5,8.8-36.1,17.5c-12.2,4.4-18,11.6-20.9,22.2c3.2,4.4,6.8,8.6,10.8,12.5c43.4,43.4,113.7,43.4,157.1,0
+			c4-4,7.6-8.2,10.8-12.5C281.375,250.225,275.475,243.025,263.375,238.625z"/>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/message.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/money.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/password.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/people.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/peoples.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/qq.svg


+ 56 - 0
src/icons/svg/raise-your-hand-to-ask.svg

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="912.1px" height="912.1px" viewBox="0 0 912.1 912.1" style="enable-background:new 0 0 912.1 912.1;" xml:space="preserve"
+	>
+<g>
+	<g>
+		<path d="M504.607,574.9c102.8,0,186.4-83.601,186.4-186.4s-83.601-186.4-186.4-186.4c-102.799,0-186.4,83.6-186.4,186.4
+			S401.808,574.9,504.607,574.9z"/>
+		<g>
+			<path d="M346.108,611.9c-71.8,0-130,58.199-130,130V887.1c0,13.801,11.2,25,25,25h527c13.8,0,25-11.199,25-25V745.5
+				c2.2-3.8,4.2-7.9,5.8-12.2l102-270c3.4-9,5.2-18.6,5.2-28.3V132c0-44.2-35.8-80-80-80s-80,35.8-80,80v288.4l-72.3,191.5H346.108z
+				"/>
+			<path d="M30.808,178.1h59c12.4,0,22.9-9,24.7-21.2c3.4-22.2,10.3-38.6,20.5-48.5c9.5-9.2,22.6-13.7,40.2-13.7
+				c18.2,0,32.1,5,42.7,15.4c10.6,10.4,15.5,22.9,15.5,39.5c0,7.8-1.8,15-5.5,22c-1.9,3.5-9.3,14.3-37.5,38.2
+				c-26.2,22.2-43.9,43.1-54.2,63.8c-10.5,21.1-15.6,51.8-15.6,93.6l0,0c0,13.8,11.2,25,25,25h53.3c13.8,0,25-11.2,25-25l0,0
+				c0-32.3,3.9-45.5,6.2-50.5c1.8-4,9.3-15.8,39-40.4c27.6-22.9,46.2-43.8,56.8-63.8c10.9-20.5,16.4-43,16.4-66.8
+				c0-42.5-16.101-78-48-105.6c-30.8-26.6-71-40.1-119.5-40.1c-46.2,0-85.3,13.8-116,40.9c-31,27.4-48.7,64.5-52.7,110.2l0,0
+				C4.708,165.5,16.208,178.1,30.808,178.1z"/>
+			<path d="M198.708,533.6c13.8,0,25-11.199,25-25V455.4c0-13.801-11.2-25-25-25h-53.2c-13.8,0-25,11.199-25,25V508.6
+				c0,13.801,11.2,25,25,25H198.708z"/>
+		</g>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/shoppingCard.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/star.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/tab.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/table.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/theme.svg


+ 0 - 0
src/icons/svg/user.svg


Some files were not shown because too many files changed in this diff