Browse Source

first commit

hexiao 1 year ago
commit
947328fab2
100 changed files with 32046 additions and 0 deletions
  1. 19 0
      .babelrc
  2. 9 0
      .editorconfig
  3. 4 0
      .eslintignore
  4. 29 0
      .eslintrc.js
  5. 16 0
      .gitignore
  6. 10 0
      .postcssrc.js
  7. 66 0
      README.md
  8. 41 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. 96 0
      build/webpack.base.conf.js
  14. 95 0
      build/webpack.dev.conf.js
  15. 148 0
      build/webpack.prod.conf.js
  16. 14 0
      config/dev.env.js
  17. 85 0
      config/index.js
  18. 8 0
      config/prod.env.js
  19. 6 0
      config/test.env.js
  20. BIN
      doc/echars柱状图堆叠加总量.png
  21. 98 0
      doc/echars柱状图堆叠加总量.txt
  22. BIN
      doc/vue培训20180806.zip
  23. 14 0
      index.html
  24. 28367 0
      package-lock.json
  25. 100 0
      package.json
  26. 95 0
      scripts/generateComponent.js
  27. 91 0
      scripts/generateView.js
  28. 101 0
      scripts/generateViewFiles.js
  29. 23 0
      scripts/template.js
  30. 23 0
      scripts/templateForFiles.js
  31. 33 0
      src/App.vue
  32. 20 0
      src/api/account/account.js
  33. 252 0
      src/api/axios.js
  34. 40 0
      src/api/call.js
  35. 64 0
      src/api/chart/chart.js
  36. 30 0
      src/api/chart/chartType.js
  37. 48 0
      src/api/da/dataQuality.js
  38. 38 0
      src/api/index.js
  39. 22 0
      src/api/kpim/common.js
  40. 67 0
      src/api/kpim/config.js
  41. 14 0
      src/api/kpim/function.js
  42. 41 0
      src/api/kpim/topic.js
  43. 46 0
      src/api/mdm/database.js
  44. 58 0
      src/api/mdm/interface.js
  45. 26 0
      src/api/mdm/kpi.js
  46. 66 0
      src/api/mdm/storage.js
  47. 59 0
      src/api/rpm/chart.js
  48. 26 0
      src/api/rpm/chartMenu.js
  49. 30 0
      src/api/rpm/menu.js
  50. 115 0
      src/api/rpm/report.js
  51. 55 0
      src/api/task/task.js
  52. 34 0
      src/api/topic/topicList.js
  53. BIN
      src/assets/3D-logo.png
  54. BIN
      src/assets/arrows-small.png
  55. BIN
      src/assets/arrows.png
  56. BIN
      src/assets/ava.jpg
  57. BIN
      src/assets/login-bg.1.jpg
  58. BIN
      src/assets/login-bg.jpg
  59. BIN
      src/assets/login-sec-bg.png
  60. BIN
      src/assets/login-thr-bg.png
  61. BIN
      src/assets/logo-icon.png
  62. BIN
      src/assets/logo.png
  63. BIN
      src/assets/logo_blue.png
  64. BIN
      src/assets/myfont/FZDHTJW.ttf
  65. 161 0
      src/assets/myfont/iconfont.css
  66. 101 0
      src/assets/myfont/iconfont.css.bak
  67. BIN
      src/assets/myfont/iconfont.eot
  68. 1 0
      src/assets/myfont/iconfont.js
  69. 134 0
      src/assets/myfont/iconfont.svg
  70. BIN
      src/assets/myfont/iconfont.ttf
  71. BIN
      src/assets/myfont/iconfont.woff
  72. BIN
      src/assets/myfont/iconfont.woff2
  73. BIN
      src/assets/pie.png
  74. BIN
      src/assets/report/biaoge1.png
  75. BIN
      src/assets/report/biaoge2.png
  76. BIN
      src/assets/report/biaoge3.png
  77. BIN
      src/assets/report/biaoge4.png
  78. BIN
      src/assets/zhexian.png
  79. BIN
      src/assets/zhu1.png
  80. BIN
      src/assets/zhu2.png
  81. BIN
      src/assets/zhu3.png
  82. BIN
      src/assets/zhu4.png
  83. 16 0
      src/class/Report/BaseClass.js
  84. 31 0
      src/class/Report/KpiDrillParam.js
  85. 12 0
      src/class/Report/recognizeType.js
  86. 16 0
      src/class/SearchTable/BaseClass.js
  87. 31 0
      src/class/SearchTable/SearchForm.js
  88. 26 0
      src/class/SearchTable/TableData.js
  89. 32 0
      src/class/SearchTable/TableLabel.js
  90. 16 0
      src/class/SearchTable/TableLabelColorOption.js
  91. 18 0
      src/class/SearchTable/TableLabelTrigger.js
  92. 14 0
      src/class/SearchTable/TableOperate.js
  93. 15 0
      src/class/SearchTable/TableOperateButton.js
  94. 29 0
      src/class/SearchTable/TableOption.js
  95. 15 0
      src/class/SearchTable/TablePageParam.js
  96. 33 0
      src/class/SearchTable/index.js
  97. 12 0
      src/class/SearchTable/recognizeType.js
  98. 346 0
      src/components/automatic-graph-components/chart.vue
  99. 68 0
      src/components/automatic-report-components/date-month.vue
  100. 0 0
      src/components/automatic-report-components/date-range.vue

+ 19 - 0
.babelrc

@@ -0,0 +1,19 @@
+{
+  "presets": [
+    ["env", {
+      "modules": false,
+      "targets": {
+        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+      }
+    }],
+    "stage-2"
+  ],
+  "plugins": ["transform-vue-jsx", "transform-runtime", [
+    "component",
+    {
+      "libraryName": "element-ui",
+      "styleLibraryName": "theme-chalk"
+    }
+  ]
+  ]
+}

+ 9 - 0
.editorconfig

@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true

+ 4 - 0
.eslintignore

@@ -0,0 +1,4 @@
+/build/
+/config/
+/dist/
+/*.js

+ 29 - 0
.eslintrc.js

@@ -0,0 +1,29 @@
+// https://eslint.org/docs/user-guide/configuring
+
+module.exports = {
+  root: true,
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  env: {
+    browser: true,
+  },
+  extends: [
+    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
+    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
+    'plugin:vue/essential', 
+    // https://github.com/standard/standard/blob/master/docs/RULES-en.md
+    'standard'
+  ],
+  // required to lint *.vue files
+  plugins: [
+    'vue'
+  ],
+  // add your custom rules here
+  rules: {
+    // allow async-await
+    'generator-star-spacing': 'off',
+    // allow debugger during development
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
+  }
+}

+ 16 - 0
.gitignore

@@ -0,0 +1,16 @@
+.idea
+.DS_Store
+node_modules/
+/dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+/.project

+ 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": {}
+  }
+}

+ 66 - 0
README.md

@@ -0,0 +1,66 @@
+# 数据中心
+
+## 部署本地编译环境:
+>
+### 部署nodeJS
+下载地址:https://nodejs.org/en/download/
+    参考教材:https://my.oschina.net/jutao/blog/1585746
+### 安装淘宝npm(cnpm)
+npm install -g cnpm --registry=https://registry.npm.taobao.org
+### 部署vue-cli
+在命令行界面执行:npm install --global vue-cli
+### 进入项目根目录
+在命令行界面执行:cnpm install
+### 执行完毕后,就可以打包项目了,打包对应的配置文件位于项目根目录下config/prod.env.js
+在命令行界面执行:node build/build.js
+
+## npm命令说明:
+
+### dev
+    读取webpack.dev.conf配置,本地默认8080端口启动
+
+### build
+    读取webpack.conf配置
+
+### build:test env
+    读取webpack.test.conf配置
+
+### new:component
+    根据输入英文名,在src/components目录生成对应组件目录
+
+### new:view
+    根据输入英文名路径/英文名,在src/views目录生成指定路径及对应vue组件文件
+    如输入test/test
+    会在src/views下生成test目录,test目录中生成test.vue文件
+
+### new:viewFiles
+    根据输入英文名路径/英文名,在src/views目录生成指定路径及对应的拆分为vue,html,js,less的组件文件
+    如输入test/test
+    会在src/views下生成test目录,test目录中生成test.vue、test.html、test.js、test.less文件
+
+## 网络资源
+
+### git排版
+>MarkDown语法<br>
+>https://www.jianshu.com/p/44ad4a22bc23
+
+
+### 二维码生成工具
+>qrcode<br>
+>https://blog.csdn.net/u010345462/article/details/81699910
+
+
+### 富文本编辑器
+>tinymce<br>
+>https://blog.csdn.net/hkweb_/article/details/81207243
+
+
+### 简单拖拽:
+>vuedraggable<br>
+>http://www.cnblogs.com/songdongdong/p/6928945.html
+
+
+### table拖拽:
+>vuedraggable+sortablejs<br>
+>https://www.jianshu.com/p/6da3043aed2a
+

+ 41 - 0
build/build.js

@@ -0,0 +1,41 @@
+'use strict'
+require('./check-versions')()
+
+process.env.NODE_ENV = 'production'
+
+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 spinner = ora('building for production...')
+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, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
+      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'
+    ))
+  })
+})

+ 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'
+  }
+}

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

@@ -0,0 +1,96 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+const vueLoaderConfig = require('./vue-loader.conf')
+require("babel-polyfill")
+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'
+  },
+  //百度地图配置20190513
+  externals: {
+    "BMap": "BMap"
+  },
+  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',
+        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        loader: 'url-loader',
+        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'
+  }
+}

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

@@ -0,0 +1,95 @@
+'use strict'
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const path = require('path')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+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: {
+      rewrites: [
+        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
+      ],
+    },
+    hot: true,
+    contentBase: false, // since we use CopyWebpackPlugin.
+    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
+    }),
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.dev.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+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)
+    }
+  })
+})

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

@@ -0,0 +1,148 @@
+'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')
+
+// const env = require('../config/prod.env')
+// 这里试一下读node的配置
+const buildEnv = process.argv.splice(2)[1] || 'prod';
+const env = require('../config/'+buildEnv+'.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.
+      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
+      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
+      allChunks: true,
+    }),
+    // 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,
+      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 vendor 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
+    }),
+
+    // 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

+ 14 - 0
config/dev.env.js

@@ -0,0 +1,14 @@
+'use strict'
+const merge = require('webpack-merge')
+const prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+  NODE_ENV: '"development"',
+
+  // BASE_URL : '"http://10.199.20.232:5432"',
+  // BASE_URL : '"http://10.199.20.238:8888/server"',
+  // BASE_URL : '"http://10.199.10.10:5555"',
+  // BASE_URL : '"http://10.199.10.10:9950/server"'
+  // BASE_URL: '"http://10.199.30.249:9191"',
+  BASE_URL : '"http://192.168.0.103:5432"',
+})

+ 85 - 0
config/index.js

@@ -0,0 +1,85 @@
+'use strict'
+// Template version: 1.3.1
+// see http://vuejs-templates.github.io/webpack for documentation.
+
+const path = require('path')
+
+module.exports = {
+  dev: {
+
+    // Paths
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable: {
+      // 测试淘宝接口
+      '/service': {
+        target: 'http://ip.taobao.com', // 接口的域名
+        // secure: false,  // 如果是https接口,需要配置这个参数
+        changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
+        pathRewrite: {
+        }
+      }
+    },
+
+    // Various Dev Server settings
+    host: '0.0.0.0', // can be overwritten by process.env.HOST
+    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
+    autoOpenBrowser: false,
+    errorOverlay: true,
+    notifyOnErrors: true,
+    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-module-eval-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,
+
+    cssSourceMap: true
+  },
+
+  build: {
+    // Template for index.html
+    index: path.resolve(__dirname, '../dist/index.html'),
+
+    // Paths
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+
+    /**
+     * Source Maps
+     */
+
+    productionSourceMap: true,
+    // 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
+  }
+}

+ 8 - 0
config/prod.env.js

@@ -0,0 +1,8 @@
+'use strict'
+module.exports = {
+  NODE_ENV: '"production"',
+  // 测试
+  // BASE_URL : '"http://10.199.10.10:5432"',
+  // 生产
+  BASE_URL : '"http://115.182.16.117:5432"',
+}

+ 6 - 0
config/test.env.js

@@ -0,0 +1,6 @@
+'use strict'
+module.exports = {
+  NODE_ENV: '"production"',
+  // 开发
+  BASE_URL : '"http://10.199.30.232:5432"',
+}

BIN
doc/echars柱状图堆叠加总量.png


+ 98 - 0
doc/echars柱状图堆叠加总量.txt

@@ -0,0 +1,98 @@
+app.title = '堆叠条形图';
+
+option = {
+    tooltip : {
+        trigger: 'axis',
+        axisPointer : {            // 坐标轴指示器,坐标轴触发有效
+            type : 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+        },
+        
+        formatter: function (params) {
+            var str = "";
+            var sum=0;
+            for (var i=0;i<params.length;i++){
+                sum+=params[i].value
+                str += params[i].seriesName+  params[i].value+"</br>";
+            }
+            return "总量" + sum + "</br>" + str;
+        }
+    },
+    legend: {
+        data: ['直接访问', '邮件营销','联盟广告','视频广告','搜索引擎']
+    },
+    grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+    },
+    yAxis:  {
+        type: 'value'
+    },
+    xAxis: {
+        type: 'category',
+        data: ['周一','周二','周三','周四','周五','周六','周日']
+    },
+    series: [
+        {
+            name: '直接访问',
+            type: 'bar',
+            stack: '总量',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'insideRight'
+                }
+            },
+            data: [320, 302, 301, 334, 390, 330, 320]
+        },
+        {
+            name: '邮件营销',
+            type: 'bar',
+            stack: '总量',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'insideRight'
+                }
+            },
+            data: [120, 132, 101, 134, 90, 230, 210]
+        },
+        {
+            name: '联盟广告',
+            type: 'bar',
+            stack: '总量',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'insideRight'
+                }
+            },
+            data: [220, 182, 191, 234, 290, 330, 310]
+        },
+        {
+            name: '视频广告',
+            type: 'bar',
+            stack: '总量',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'insideRight'
+                }
+            },
+            data: [150, 212, 201, 154, 190, 330, 410]
+        },
+        {
+            name: '搜索引擎',
+            type: 'bar',
+            stack: '总量',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'insideRight'
+                }
+            },
+            data: [820, 832, 901, 934, 1290, 1330, 1320]
+        }
+    ]
+};

BIN
doc/vue培训20180806.zip


+ 14 - 0
index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=In1kbmAkvGmImKLHG5orWexGG73rvkFF"></script>
+    <script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
+    <title>数据中心</title>
+  </head>
+  <body id="body" class="theme">
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

File diff suppressed because it is too large
+ 28367 - 0
package-lock.json


+ 100 - 0
package.json

@@ -0,0 +1,100 @@
+{
+  "name": "test-element",
+  "version": "1.0.0",
+  "description": "A Vue.js project",
+  "author": "feifei1030 <964668506@qq.com>",
+  "private": true,
+  "scripts": {
+    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+    "start": "npm run dev",
+    "lint": "eslint --ext .js,.vue src",
+    "build": "node build/build.js",
+    "build:test env": "node build/build.js -- test",
+    "build:dev env": "node build/build.js -- dev",
+    "new:component": "node ./scripts/generateComponent",
+    "new:view": "node ./scripts/generateView",
+    "new:viewFiles": "node ./scripts/generateViewFiles"
+  },
+  "dependencies": {
+    "@tinymce/tinymce-vue": "1.1.2",
+    "axios": "~0.18.0",
+    "babel-polyfill": "~6.26.0",
+    "echarts": "~4.1.0",
+    "element-ui": "~2.11.1",
+    "fastclick": "~1.0.6",
+    "js-cookie": "~2.2.1",
+    "less": "~3.9.0",
+    "less-loader": "~4.1.0",
+    "m-share": "~1.0.1",
+    "nativeshare": "~2.1.3",
+    "qrcode": "~1.3.2",
+    "sass-loader": "~7.1.0",
+    "sortablejs": "~1.7.0",
+    "tinymce": "~4.9.2",
+    "tinymce-vue": "~1.0.0",
+    "vue": "~2.6.10",
+    "vue-router": "~3.0.1",
+    "vuedraggable": "~2.17.0",
+    "vuex": "~3.1.1"
+  },
+  "devDependencies": {
+    "autoprefixer": "~7.1.2",
+    "babel-core": "~6.26.1",
+    "babel-eslint": "~8.2.6",
+    "babel-helper-vue-jsx-merge-props": "~2.0.3",
+    "babel-loader": "~7.1.5",
+    "babel-plugin-component": "~1.1.1",
+    "babel-plugin-syntax-jsx": "~6.18.0",
+    "babel-plugin-transform-runtime": "~6.23.0",
+    "babel-plugin-transform-vue-jsx": "~3.7.0",
+    "babel-preset-env": "~1.7.0",
+    "babel-preset-stage-2": "~6.24.0",
+    "chalk": "~2.4.2",
+    "copy-webpack-plugin": "~4.6.0",
+    "css-loader": "~0.28.11",
+    "eslint": "~4.19.0",
+    "eslint-config-standard": "~10.2.1",
+    "eslint-friendly-formatter": "~3.0.0",
+    "eslint-loader": "~1.9.0",
+    "eslint-plugin-import": "~2.18.2",
+    "eslint-plugin-node": "~5.2.1",
+    "eslint-plugin-promise": "~3.8.0",
+    "eslint-plugin-standard": "~3.1.0",
+    "eslint-plugin-vue": "~4.7.1",
+    "event-source-polyfill": "0.0.12",
+    "extract-text-webpack-plugin": "~3.0.2",
+    "file-loader": "~1.1.11",
+    "friendly-errors-webpack-plugin": "~1.7.0",
+    "html-webpack-plugin": "~2.30.1",
+    "node-notifier": "~5.4.0",
+    "optimize-css-assets-webpack-plugin": "~3.2.1",
+    "ora": "~1.4.0",
+    "portfinder": "~1.0.21",
+    "postcss-import": "~11.1.0",
+    "postcss-loader": "~2.1.6",
+    "postcss-url": "~7.3.2",
+    "rimraf": "~2.6.3",
+    "semver": "~5.7.0",
+    "shelljs": "~0.7.8",
+    "uglifyjs-webpack-plugin": "~1.3.0",
+    "url-loader": "~0.5.9",
+    "vue-kindeditor": "~0.4.5",
+    "vue-loader": "~13.7.3",
+    "vue-style-loader": "~3.1.2",
+    "vue-template-compiler": "~2.6.10",
+    "webpack": "~3.12.0",
+    "webpack-bundle-analyzer": "~2.13.1",
+    "webpack-dev-server": "~2.11.5",
+    "webpack-merge": "~4.2.1"
+  },
+  "engines": {
+    "node": ">= 6.0.0",
+    "npm": ">= 3.0.0"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 5 versions",
+    "Android >= 4.0",
+    "not ie <= 8"
+  ]
+}

+ 95 - 0
scripts/generateComponent.js

@@ -0,0 +1,95 @@
+// generateComponent.js`
+const chalk = require('chalk')
+const path = require('path')
+const fs = require('fs')
+const resolve = (...file) => path.resolve(__dirname, ...file)
+const log = message => console.log(chalk.green(`${message}`))
+const successLog = message => console.log(chalk.blue(`${message}`))
+const errorLog = error => console.log(chalk.red(`${error}`))
+const { vueTemplate, entryTemplate } = require('./template')
+
+const generateFile = (path, data) => {
+  if (fs.existsSync(path)) {
+    errorLog(`${path}文件已存在`)
+    return
+  }
+  return new Promise((resolve, reject) => {
+    fs.writeFile(path, data, 'utf8', err => {
+      if (err) {
+        errorLog(err.message)
+        reject(err)
+      } else {
+        resolve(true)
+      }
+    })
+  })
+}
+log('请输入要生成的组件名称、如需生成全局组件,请加 global/ 前缀')
+let componentName = ''
+process.stdin.on('data', async chunk => {
+  const inputName = String(chunk).trim().toString()
+  /**
+   * 组件目录路径
+   */
+  const componentDirectory = resolve('../src/components', inputName)
+
+  /**
+   * vue组件路径
+   */
+  const componentVueName = resolve(componentDirectory, 'main.vue')
+  /**
+   * 入口文件路径
+   */
+  const entryComponentName = resolve(componentDirectory, 'index.js')
+
+  const hasComponentDirectory = fs.existsSync(componentDirectory)
+  if (hasComponentDirectory) {
+    errorLog(`${inputName}组件目录已存在,请重新输入`)
+    return
+  } else {
+    log(`正在生成 component 目录 ${componentDirectory}`)
+    await dotExistDirectoryCreate(componentDirectory)
+    // fs.mkdirSync(componentDirectory);
+  }
+  try {
+    if (inputName.includes('/')) {
+      const inputArr = inputName.split('/')
+      componentName = inputArr[inputArr.length - 1]
+    } else {
+      componentName = inputName
+    }
+    log(`正在生成 vue 文件 ${componentVueName}`)
+    await generateFile(componentVueName, vueTemplate(componentName))
+    log(`正在生成 entry 文件 ${entryComponentName}`)
+    await generateFile(entryComponentName, entryTemplate)
+    successLog('生成成功')
+  } catch (e) {
+    errorLog(e.message)
+  }
+
+  process.stdin.emit('end')
+})
+process.stdin.on('end', () => {
+  log('exit')
+  process.exit()
+})
+function dotExistDirectoryCreate (directory) {
+  return new Promise((resolve) => {
+    mkdirs(directory, function () {
+      resolve(true)
+    })
+  })
+}
+
+// 递归创建目录
+function mkdirs (directory, callback) {
+  var exists = fs.existsSync(directory)
+  if (exists) {
+    callback()
+  } else {
+    mkdirs(path.dirname(directory), function () {
+      fs.mkdirSync(directory)
+      callback()
+    })
+  }
+}

+ 91 - 0
scripts/generateView.js

@@ -0,0 +1,91 @@
+// generateView.js
+const chalk = require('chalk')
+const path = require('path')
+const fs = require('fs')
+const resolve = (...file) => path.resolve(__dirname, ...file)
+const log = message => console.log(chalk.green(`${message}`))
+const successLog = message => console.log(chalk.blue(`${message}`))
+const errorLog = error => console.log(chalk.red(`${error}`))
+const { vueTemplate } = require('./template')
+
+const generateFile = (path, data) => {
+  if (fs.existsSync(path)) {
+    errorLog(`${path}文件已存在`)
+    return
+  }
+  return new Promise((resolve, reject) => {
+    fs.writeFile(path, data, 'utf8', err => {
+      if (err) {
+        errorLog(err.message)
+        reject(err)
+      } else {
+        resolve(true)
+      }
+    })
+  })
+}
+log('请输入要生成的页面组件名称、会生成在 views/目录下')
+let componentName = ''
+process.stdin.on('data', async chunk => {
+  const inputName = String(chunk).trim().toString()
+  /**
+   * Vue页面组件路径
+   */
+  let componentVueName = resolve('../src/views', inputName)
+  // 如果不是以 .vue 结尾的话,自动加上
+  if (!componentVueName.endsWith('.vue')) {
+    componentVueName += '.vue'
+  }
+  /**
+   * vue组件目录路径
+   */
+  const componentDirectory = path.dirname(componentVueName)
+
+  const hasComponentExists = fs.existsSync(componentVueName)
+  if (hasComponentExists) {
+    errorLog(`${inputName}页面组件已存在,请重新输入`)
+    return
+  } else {
+    log(`正在生成 component 目录 ${componentDirectory}`)
+    await dotExistDirectoryCreate(componentDirectory)
+  }
+  try {
+    if (inputName.includes('/')) {
+      const inputArr = inputName.split('/')
+      componentName = inputArr[inputArr.length - 1]
+    } else {
+      componentName = inputName
+    }
+    log(`正在生成 vue 文件 ${componentVueName}`)
+    await generateFile(componentVueName, vueTemplate(componentName))
+    successLog('生成成功')
+  } catch (e) {
+    errorLog(e.message)
+  }
+
+  process.stdin.emit('end')
+})
+process.stdin.on('end', () => {
+  log('exit')
+  process.exit()
+})
+function dotExistDirectoryCreate (directory) {
+  return new Promise((resolve) => {
+    mkdirs(directory, function () {
+      resolve(true)
+    })
+  })
+}
+
+// 递归创建目录
+function mkdirs (directory, callback) {
+  var exists = fs.existsSync(directory)
+  if (exists) {
+    callback()
+  } else {
+    mkdirs(path.dirname(directory), function () {
+      fs.mkdirSync(directory)
+      callback()
+    })
+  }
+}

+ 101 - 0
scripts/generateViewFiles.js

@@ -0,0 +1,101 @@
+// generateView.js
+const chalk = require('chalk')
+const path = require('path')
+const fs = require('fs')
+const resolve = (...file) => path.resolve(__dirname, ...file)
+const log = message => console.log(chalk.green(`${message}`))
+const successLog = message => console.log(chalk.blue(`${message}`))
+const errorLog = error => console.log(chalk.red(`${error}`))
+const {jsFileTemplate,vueFileTemplate } = require('./templateForFiles')
+
+const generateFile = (path, data) => {
+  if (fs.existsSync(path)) {
+    errorLog(`${path}文件已存在`)
+    return
+  }
+  return new Promise((resolve, reject) => {
+    fs.writeFile(path, data, 'utf8', err => {
+      if (err) {
+        errorLog(err.message)
+        reject(err)
+      } else {
+        resolve(true)
+      }
+    })
+  })
+}
+log('请输入要生成的页面组件名称、会生成在 views/目录下')
+let componentName = ''
+process.stdin.on('data', async chunk => {
+  const inputName = String(chunk).trim().toString()
+  /**
+   * Vue页面组件路径
+   */
+  let componentVueName = resolve('../src/views', inputName)
+
+  let componentJsName = componentVueName+'.js'
+  let componentLessName = componentVueName+'.less'
+  let componentHtmlName = componentVueName+'.html'
+  // 如果不是以 .vue 结尾的话,自动加上
+  if (!componentVueName.endsWith('.vue')) {
+    componentVueName += '.vue'
+  }
+  /**
+   * vue组件目录路径
+   */
+  const componentDirectory = path.dirname(componentVueName)
+
+  const hasComponentExists = fs.existsSync(componentVueName)
+  if (hasComponentExists) {
+    errorLog(`${inputName}页面组件已存在,请重新输入`)
+    return
+  } else {
+    log(`正在生成 component 目录 ${componentDirectory}`)
+    await dotExistDirectoryCreate(componentDirectory)
+  }
+  try {
+    if (inputName.includes('/')) {
+      const inputArr = inputName.split('/')
+      componentName = inputArr[inputArr.length - 1]
+    } else {
+      componentName = inputName
+    }
+    log(`正在生成 vue 文件 ${componentVueName}`)
+    await generateFile(componentVueName, vueFileTemplate(componentName))
+    log(`正在生成 js 文件 ${componentJsName}`)
+    await generateFile(componentJsName, jsFileTemplate(componentName))
+    log(`正在生成 html 文件 ${componentHtmlName}`)
+    await generateFile(componentHtmlName, '')
+    log(`正在生成 less 文件 ${componentLessName}`)
+    await generateFile(componentLessName, '')
+    successLog('生成成功')
+  } catch (e) {
+    errorLog(e.message)
+  }
+
+  process.stdin.emit('end')
+})
+process.stdin.on('end', () => {
+  log('exit')
+  process.exit()
+})
+function dotExistDirectoryCreate (directory) {
+  return new Promise((resolve) => {
+    mkdirs(directory, function () {
+      resolve(true)
+    })
+  })
+}
+
+// 递归创建目录
+function mkdirs (directory, callback) {
+  var exists = fs.existsSync(directory)
+  if (exists) {
+    callback()
+  } else {
+    mkdirs(path.dirname(directory), function () {
+      fs.mkdirSync(directory)
+      callback()
+    })
+  }
+}

+ 23 - 0
scripts/template.js

@@ -0,0 +1,23 @@
+// template.js
+module.exports = {
+  vueTemplate: compoenntName => {
+    return `<template>
+  <div class="${compoenntName}">
+    ${compoenntName}组件
+  </div>
+</template>
+<script>
+export default {
+  name: '${compoenntName}'
+}
+</script>
+<style lang="less" scoped>
+.${compoenntName} {
+
+}
+</style>
+`
+  },
+  entryTemplate: `import Main from './main.vue'
+export default Main`
+}

+ 23 - 0
scripts/templateForFiles.js

@@ -0,0 +1,23 @@
+// template.js
+module.exports = {
+  jsFileTemplate: compoenntName => {
+    return `export default {
+  name: '${compoenntName}',
+  data () {
+    return {
+    }
+  },
+  mounted () {
+  },
+  methods: {
+  }
+}`
+  },
+  vueFileTemplate: compoenntName => {
+    return `<template src="./${compoenntName}.html"></template>
+<script src="./${compoenntName}.js"></script>
+<style src="./${compoenntName}.less" lang="less" scoped></style>
+`
+  },
+}
+

+ 33 - 0
src/App.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="app" >
+    <router-view/>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'App',
+    data () {
+      return {
+        defaultActive: 'searchClue'
+      }
+    },
+    methods: {
+      go (key) {
+        // this.$router.push(key);
+      },
+      handleOpen (key, keyPath) {
+        console.log(key, keyPath)
+      },
+      handleClose (key, keyPath) {
+        console.log(key, keyPath)
+      }
+    },
+    created () {
+      this.defaultActive=this.$route.path.split('/')[1]
+    }
+  }
+</script>
+
+<style>
+</style>

+ 20 - 0
src/api/account/account.js

@@ -0,0 +1,20 @@
+import Api from '../axios'
+
+const prefix = '/account/account'
+
+export default {
+
+  /* 登录 */
+  login (obj) {
+    return Api.post(prefix + '/login', obj)
+  },
+  getAuthCode () {
+    return Api.get(prefix + '/authCode')
+  },
+  ifAuthCodeCorrect (obj) {
+    return Api.get(prefix + '/ifAuthCodeCorrect', obj)
+  },
+  changeTheme (obj) {
+    return Api.get(prefix + '/changeTheme', obj)
+  }
+}

+ 252 - 0
src/api/axios.js

@@ -0,0 +1,252 @@
+import Axios from 'axios'
+import QS from 'querystring'
+import Call from './call'
+import router from '../router/index'
+import {
+  Message
+} from 'element-ui'
+
+// TODO baseURL
+let AUTH_TOKEN = localStorage.getItem('token') || ''
+
+// 生产环境
+// var urls = 'http://ad.data-u.com:8888';
+// var frontUrl = 'http://ad.data-u.com:16081';
+
+
+// // 测试环境
+// var urls = 'http://10.199.10.8:8888';
+// var frontUrl = 'http://10.199.10.8:16062';
+
+
+// // 开发环境
+// var urls = 'http://10.199.10.9:8888';
+// var frontUrl = 'http://10.199.20.227:8000';
+
+Axios.defaults.baseURL = process.env.BASE_URL
+Axios.defaults.headers.common['token'] = AUTH_TOKEN
+
+Axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
+// Axios.defaults.headers.post['Accept'] = '*/*'
+
+// TODO 设置超时时间
+Axios.defaults.timeout = 20000
+
+// TODO http code 校验
+Axios.defaults.validateStatus = function (status) {
+  return status
+}
+
+// TODO GET 请求 params 序列化
+Axios.defaults.paramsSerializer = function (params) {
+  // 将对象解析成URL的形式
+  return QS.stringify(params)
+}
+
+// TODO 设置POST等请求 body 序列化
+// Axios.defaults.transformRequest = [function (body) {
+//   let data = body || {}
+//   if (data instanceof window.FormData) {
+//     return data
+//   }
+//   return QS.stringify(data)
+// }]
+
+// request拦截器
+Axios.interceptors.request.use(config => {
+  config.headers.token = localStorage.getItem('token')
+  return config
+}, error => {
+  // Do something with request error
+  return Promise.reject(error)
+})
+
+// TODO 设置统一请求拦截
+Axios.interceptors.response.use(res => {
+  if (res.headers.token) {
+    localStorage.setItem('token', res.headers.token)
+  }
+
+  if (res.status === 200) {
+    // 会话过期  当前会话已过期,请重新访问。
+    //
+    // 423代表权限不允许,继没有传token
+    // 403代表token异常,即token过期
+    // -1代表内部异常
+    if (res.data.hasOwnProperty('code') && res.data.code == 403) {
+      localStorage.setItem('token', '')
+      document.getElementById('body').className = "theme-white"
+
+      router.replace({
+        path: '/login',
+        // query: {redirect: router.currentRoute.fullPath}
+        query: {redirect: router.currentRoute.path}
+
+      })
+    } else if (res.data.hasOwnProperty('code') &&  (res.data.code == -1 || res.data.code>1)) {
+      // alert(res.data.msg)
+      Message({
+        type: 'error',
+        message: res.data.msg
+      })
+    }
+    return Promise.resolve(res.data)
+  }
+  return Promise.reject(res.data)
+}, error => {
+  return Promise.reject(error)
+})
+
+/**
+ * @description 统一 GET 请求
+ * @param url
+ * @param params --> GET 请求参数(***?name=walid&age=25)
+ */
+function get (url, params={}) {
+  return new Call((resolve, reject) => {
+    let timestamp = (new Date()).valueOf()
+    params.timestamp = timestamp
+    Axios.get(url, {params: params})
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+/**
+ * @description 统一 POST 请求
+ * @param url
+ * @param body --> POST 请求 data
+ */
+function post (url, body) {
+  return new Call((resolve, reject) => {
+    Axios.post(url, body)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+/**
+ * @description 统一 Put 请求
+ * @param url
+ * @param body --> Put 请求 data
+ */
+function put (url, body) {
+  return new Call((resolve, reject) => {
+    Axios.put(url, body)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+function uploadFile (url, payload) {
+  return new Call((resolve, reject) => {
+    let config = {
+      headers: {'Content-Type': 'multipart/form-data'}
+    }
+
+    Axios({
+      url: url,
+      config: config,
+      method: 'post',
+      data: payload
+    }).then(response => {
+      resolve(response)
+    }).catch(error => {
+      reject(error)
+    })
+  })
+}
+
+
+/**
+ * @description 统一 GET 请求
+ * @param url
+ * @param params --> GET 请求参数(***?name=walid&age=25)
+ */
+function getById (url, params) {
+  return new Call((resolve, reject) => {
+    let id = typeof params === 'object' ? params.id : params
+    let timestamp = (new Date()).valueOf()
+    let obj = typeof params==='object'?params:{}
+    obj.timestamp = timestamp
+
+    Axios.get(url + '/' + id, obj)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+/**
+ * @description 统一 put 请求
+ * @param url
+ * @param params --> put 请求参数
+ */
+function putById (url, params) {
+  return new Call((resolve, reject) => {
+    Axios.put(url + '/' + params.id, params)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+/**
+ * @description 统一 delete 请求
+ * @param url
+ * @param params --> delete 请求参数
+ */
+function deleteById (url, params) {
+  let id = typeof params === 'object' ? params.id : params
+
+  return new Call((resolve, reject) => {
+    Axios.delete(url + '/' + id)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+/**
+ * @description 统一 delete 请求
+ * @param url
+ * @param params --> delete 请求参数
+ */
+function del (url, params) {
+  return new Call((resolve, reject) => {
+    Axios.delete(url,params)
+      .then(response => {
+        resolve(response)
+      })
+      .catch(error => {
+        reject(error)
+      })
+  })
+}
+
+function direct (url) {
+  return url
+}
+export default {
+  get, post, put, direct, uploadFile, putById, deleteById, getById, del
+}

+ 40 - 0
src/api/call.js

@@ -0,0 +1,40 @@
+export default class Call {
+  constructor (executor) {
+    let self = this
+    try {
+      executor(function (res) {
+        self._dispatchResolve(res)
+      }, function (errRes) {
+        self._dispatchReject(errRes)
+      })
+    } catch (err) {
+      self._dispatchReject(err)
+    }
+  }
+
+  then (onResolved) {
+    this.resolve = onResolved
+    return this
+  }
+
+  catch (onRejected) {
+    this.reject = onRejected
+    return this
+  }
+
+  _dispatchResolve (response) {
+    if (Call._isFunc(this.resolve)) {
+      this.resolve(response)
+    }
+  }
+
+  _dispatchReject (error) {
+    if (Call._isFunc(this.reject)) {
+      this.reject(error)
+    }
+  }
+
+  static _isFunc (obj) {
+    return obj && typeof obj === 'function'
+  }
+}

+ 64 - 0
src/api/chart/chart.js

@@ -0,0 +1,64 @@
+import Api from '../axios'
+
+const prefix = '/appshow/appshow/chartInfo'
+const prefixOfType = '/appshow/appshow'
+let AUTH_TOKEN = localStorage.getItem('token') || ''
+export default {
+
+  /* 保存图表信息 */
+  addChartInfo (obj) {
+    return Api.post(prefix, obj)
+  },
+  uploadFile (obj) {
+    return Api.uploadFile(prefix + '/loadChartFile', obj)
+  },
+  /* 根据数据库和表信息生成获取DML */
+  getDML (obj) {
+    return Api.get(prefix + '/getDML', obj)
+  },
+  /* 图表分页列表展示 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+  /* 通过分类编号获取分类下图表 */
+  listByClass (obj) {
+    return Api.get(prefix + '/listByClass', obj)
+  },
+  /* 获取根据数据库ID获取字段信息 */
+  listColumnByTableId (obj) {
+    return Api.get(prefix + '/listColumnByTableId', obj)
+  },
+  /** 获取MDM数据库列表-非原始库 */
+  listDatabase (obj) {
+    return Api.get(prefix + '/listDatabase', obj)
+  },
+  /* 获取根据数据库ID获取数据表信息-非原始库 */
+  listTableByDatabaseId (obj) {
+    return Api.get(prefix + '/listTableByDatabaseId', obj)
+  },
+  /* 获取图表类型 */
+  chartType (obj) {
+    return Api.get(prefixOfType + '/chartType', obj)
+  },
+  /* 图表配置接口 */
+  updateChartJson (obj) {
+    return Api.put(prefixOfType + '/updateChartJson', obj)
+  },
+  /* 根据ID获取图表信息 */
+  getChartById (obj) {
+    return Api.getById(prefix + "/" , obj)
+  },
+  /* 图表预览接口 */
+  chartView (obj) {
+    return Api.getById(prefixOfType + "/chartView", obj)
+  },
+  /* 分类信息修改接口 */
+  updateChartInfo (obj) {
+    return Api.putById(prefix + "/" , obj);
+  },
+  /* 删除接口 */
+  delChartInfo (obj) {
+    return Api.deleteById(prefix + "/" , obj)
+  },
+  fileUpload: process.env.BASE_URL + prefix + "/loadRichTextFile?token=" + AUTH_TOKEN
+}

+ 30 - 0
src/api/chart/chartType.js

@@ -0,0 +1,30 @@
+import Api from '../axios'
+
+const prefix = '/appshow/appshow/chartClass'
+
+export default {
+
+  /* 新建图表分类接口 */
+  addChartClass(obj) {
+    return Api.post(prefix + '/', obj)
+  },
+  /* 通过菜单名模糊搜索获取菜单树状展示 */
+  getChartClassTree() {
+    return Api.get(prefix + '/tree')
+  },
+  /* 通过分类编码获取图表分类信息 */
+  getChartClassTreeByCode(obj) {
+    let classCode = typeof obj === 'object' ? obj.classCode : "";
+    return Api.get(prefix + '/' + classCode, obj)
+  },
+  /* 分类信息修改接口 */
+  updateChartClass(obj) {
+    let classCode = typeof obj === 'object' ? obj.classCode : "";
+    return Api.put(prefix + '/' + classCode, obj)
+  },
+  /* 分类删除接口 */
+  delChartClass(obj) {
+    let classCode = typeof obj === 'object' ? obj.classCode : "";
+    return Api.del(prefix + '/' + classCode, obj)
+  }
+}

+ 48 - 0
src/api/da/dataQuality.js

@@ -0,0 +1,48 @@
+import Api from '../axios'
+
+const prefix = '/da/da/dataQuality'
+
+export default {
+
+  // 获取数据库列表--非原始库
+  listDatabase (obj) {
+    return Api.get(prefix + '/listDatabase', obj)
+  },
+
+  // 通过数据库ID获取表数据列表
+  listTableByDatabaseId (obj) {
+    return Api.get(prefix + '/listTableByDatabaseId', obj)
+  },
+
+  // 通过表ID获取字段信息列表
+  getQuerySql (obj) {
+    return Api.get(prefix + '/getQuerySql', obj)
+  },
+
+  // 获取表中数据接口
+  listData (obj) {
+    return Api.get(prefix + '/listData', obj)
+  },
+
+  // 下载模板
+  downloadTemplateData (obj) {
+    return Api.get(prefix + '/downloadTemplateData', obj)
+  },
+
+  // 字段模板上传
+  uploadTemplateData (obj) {
+    return Api.uploadPhoto(prefix + '/uploadTemplateData', obj)
+  },
+
+  // 删除表中数据接口
+  deleteData (obj) {
+    return Api.post(prefix + '/deleteData', obj)
+  },
+
+  // 修改表中数据接口
+  updateData (obj) {
+    return Api.post(prefix + '/updateData', obj)
+  }
+
+
+}

+ 38 - 0
src/api/index.js

@@ -0,0 +1,38 @@
+import database from './mdm/database'
+import kpi from './mdm/kpi'
+import storage from './mdm/storage'
+import interfaceDb from './mdm/interface'
+import account from './account/account'
+import kpiConfig from './kpim/config'
+import kpiCommon from './kpim/common'
+import kpiFunction from './kpim/function'
+import menu from './rpm/menu'
+import report from './rpm/report'
+import chart from './rpm/chart'
+import chartMenu from './rpm/chartMenu'
+import kpiTopic from './kpim/topic'
+import task from './task/task'
+import dataQuality from './da/dataQuality'
+import chartType from './chart/chartType'
+// import chart from './chart/chart'
+import topicList from './topic/topicList'
+
+export default {
+  account,
+  database,
+  kpi,
+  storage,
+  kpiConfig,
+  kpiCommon,
+  kpiFunction,
+  menu,
+  chartMenu,
+  report,
+  kpiTopic,
+  task,
+  dataQuality,
+  chartType,
+  chart,
+  interfaceDb,
+  topicList
+}

+ 22 - 0
src/api/kpim/common.js

@@ -0,0 +1,22 @@
+import Api from '../axios'
+
+const prefix = '/kpim/kpim/common'
+
+export default {
+  /* 查询普通管理员列表 */
+  listAdministrativeUsers (obj) {
+    return Api.get(prefix + '/listAdministrativeUsers', obj)
+  },
+  /* 根据KPI类型查询规则类型列表 */
+  listRuleTypesByKpiType (obj) {
+    return Api.get(prefix + '/listRuleTypesByKpiType', obj)
+  },
+  /* 查询符号列表 */
+  listSigns (obj) {
+    return Api.get(prefix + '/listSigns', obj)
+  },
+  /* 查询配置类型列表 */
+  listTypes (obj) {
+    return Api.get(prefix + '/listTypes', obj)
+  }
+}

+ 67 - 0
src/api/kpim/config.js

@@ -0,0 +1,67 @@
+import Api from '../axios'
+
+const prefix = '/kpim/kpim/kpiConfig'
+
+export default {
+  /* 创建KPI批量新增 */
+  batchSave (obj) {
+    return Api.post(prefix + '/batchSave', obj)
+  },
+  /* 删除KPI配置 */
+  delete (obj) {
+    return Api.deleteById(prefix + '/delete', obj)
+  },
+  /* 查看KPI配置详情 */
+  getById (obj) {
+    return Api.getById(prefix + '/getById', obj)
+  },
+  /* 查询KPI配置列表(分页) */
+  listKpiConfigs (obj) {
+    return Api.get(prefix + '/listKpiConfigs', obj)
+  },
+  /* 根据主题查询KPI列表 */
+  listKpiConfigsByTopic (obj) {
+    return Api.get(prefix + '/listKpiConfigsByTopic', obj)
+  },
+  /* 创建KPI一条 */
+  save (obj) {
+    return Api.post(prefix + '/save', obj)
+  },
+  /* 权限控制保存 */
+  savePrivilegeControlRelations (obj) {
+    return Api.post(prefix + '/savePrivilegeControlRelations', obj)
+  },
+  /* 修改KPI配置 */
+  update (obj) {
+    return Api.put(prefix + '/update', obj)
+  },
+
+  /* 元数据字段下拉列表查询 */
+  listMdmColumnsByTable (obj) {
+    return Api.get(prefix + '/listMdmColumnsByTable', obj)
+  },
+  /* 元数据字段分页查询 */
+  listMdmColumnsWithPages (obj) {
+    return Api.get(prefix + '/listMdmColumnsWithPages', obj)
+  },
+  /* 元数据库下拉列表查询 */
+  listMdmDatabases (obj) {
+    return Api.get(prefix + '/listMdmDatabases', obj)
+  },
+  /* 元数据表下拉列表查询 */
+  listMdmTablesByDatabase (obj) {
+    return Api.get(prefix + '/listMdmTablesByDatabase', obj)
+  },
+  /* 根据databaseId查询字段并按照table分组 */
+  listMdmColumnsGroupByTable (obj) {
+    return Api.get(prefix + '/listMdmColumnsGroupByTable', obj)
+  },
+
+  /**
+   * 启用/停用操作
+   */
+  updateEnableStatus (obj) {
+    return Api.put(prefix + '/updateEnableStatus', obj)
+  }
+
+}

+ 14 - 0
src/api/kpim/function.js

@@ -0,0 +1,14 @@
+import Api from '../axios'
+
+const prefix = '/kpim/kpim/kpiFunction'
+
+export default {
+  /* KPI函数列表查询 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+  /* KPI函数详情 */
+  getById (obj) {
+    return Api.get(prefix + '/', obj)
+  }
+}

+ 41 - 0
src/api/kpim/topic.js

@@ -0,0 +1,41 @@
+import Api from '../axios'
+
+const prefix = '/kpim/kpim/topic'
+
+export default {
+  /* 删除主题 */
+  delete (obj) {
+    return Api.deleteById(prefix + '/deleteByTopicCode', obj)
+  },
+  /* 查询主题详情 */
+  getById (obj) {
+    return Api.get(prefix + '/getById', obj)
+  },
+  getByTopicCode (obj) {
+    return Api.getById(prefix + '/getByTopicCode', obj)
+  },
+  /* 查询主题的直接下级主题 */
+  listSubTopics (obj) {
+    return Api.get(prefix + '/listSubTopics', obj)
+  },
+  /* 查询主题列表(分页) */
+  listTopics (obj) {
+    return Api.get(prefix + '/listTopics', obj)
+  },
+  /* 创建主题 */
+  save (obj) {
+    return Api.post(prefix + '/save', obj)
+  },
+  /* 查询主题树 */
+  topicTree (obj) {
+    return Api.get(prefix + '/topicTree', obj)
+  },
+  /* 查询主题树Ztree */
+  topicTtree (obj) {
+    return Api.get(prefix + '/topicForZtree', obj)
+  },
+  /* 修改主题 */
+  update (obj) {
+    return Api.put(prefix + '/update', obj)
+  }
+}

+ 46 - 0
src/api/mdm/database.js

@@ -0,0 +1,46 @@
+import Api from '../axios'
+
+const prefix = '/mdm/mdm/databaseManage'
+
+export default {
+  /* 通过id获取数据库信息 */
+  getDatabaseById (obj) {
+    return Api.getById(prefix + '/getDatabaseById', obj)
+  },
+  /* 测试数据库连接资源 */
+  getTestConnection (obj) {
+    return Api.get(prefix + '/getTestConnection', obj)
+  },
+  /* 获取字符集列表 */
+  listCharsetType (obj) {
+    return Api.get(prefix + '/listCharsetType', obj)
+  },
+  /* 获取数据库资源列表接口 */
+  listDatabase (obj) {
+    return Api.get(prefix + '/listDatabase', obj)
+  },
+  /* 获取数据库类型列表 */
+  listDatabaseType (obj) {
+    return Api.get(prefix + '/listDatabaseType', obj)
+  },
+  /* 获取资源类型列表 */
+  listResourceType (obj) {
+    return Api.get(prefix + '/listResourceType', obj)
+  },
+  /* 根据ID删除数据库资源接口 */
+  removeDatabaseById (obj) {
+    return Api.deleteById(prefix + '/removeDatabaseById', obj)
+  },
+  /* 新建数据库资源接口 */
+  saveDatabase (obj) {
+    return Api.post(prefix + '/saveDatabase', obj)
+  },
+  /* 修改数据库资源接口 */
+  updateDatabase (obj) {
+    return Api.put(prefix + '/updateDatabase', obj)
+  },
+  /* 刷新数据库 */
+  refreshDB (obj) {
+    return Api.putById(prefix + '/refresh', obj)
+  }
+}

+ 58 - 0
src/api/mdm/interface.js

@@ -0,0 +1,58 @@
+import Api from '../axios'
+
+const prefix = '/mdm/mdm/interfaceDataSources'
+
+export default {
+  /* 获取接口列表 */
+  listInterfaceDataSources (obj) {
+    return Api.get(prefix + '/listInterfaceDataSources', obj)
+  },
+  /* 数据源管理单条数据源详细信息 */
+  getInterfaceDataSourcesById (obj) {
+    return Api.getById(prefix + '/getInterfaceDataSourcesById', obj)
+  },
+  /* 数据源管理单条数据源详细信息测试 */
+  testInterfaceDataSources (obj) {
+    return Api.post(prefix + '/testInterfaceDataSources', obj)
+  },
+  /* 数据源管理单条数据源信息接口请求方式查询 */
+  listRequestMode (obj) {
+    return Api.get(prefix + '/listRequestMode', obj)
+  },
+  /* 数据源管理单条数据源信息接口状态修改 */
+  updateInterfaceDataSourcesStatus (obj) {
+    return Api.putById(prefix + '/updateInterfaceDataSourcesStatus', obj)
+  },
+  /* 数据源管理单条数据源信息删除 */
+  deleteInterfaceDataSources (obj) {
+    return Api.deleteById(prefix + '/deleteInterfaceDataSources', obj)
+  },
+  /* 数据源管理单条数据源信息新增 */
+  addInterfaceDataSources (obj) {
+    return Api.post(prefix + '/addInterfaceDataSources', obj)
+  },
+  /* 数据源管理数据源信息接口分类新增 */
+  addInterfaceProject (obj) {
+    return Api.post(prefix + '/addInterfaceProject', obj)
+  },
+  /* 数据源管理单条数据源信息修改 */
+  updateInterfaceDataSourcesById (obj) {
+    return Api.putById(prefix + '/updateInterfaceDataSourcesById', obj)
+  },
+  /* 数据源管理数据源信息接口分类修改 */
+  updateInterfaceProjectById (obj) {
+    return Api.putById(prefix + '/updateInterfaceProjectById', obj)
+  },
+  /* 数据源管理数据源信息接口分类BYid */
+  getInterfaceProjectById (obj) {
+    return Api.getById(prefix + '/getInterfaceProjectById', obj)
+  },
+  /* 数据源管理数据源信息接口分类查询 */
+  listInterfaceProject (obj) {
+    return Api.get(prefix + '/listInterfaceProject', obj)
+  },
+  /* 数据源管理数据源信息接口分类删除 */
+  deleteInterfaceProject (obj) {
+    return Api.deleteById(prefix + '/deleteInterfaceProject', obj)
+  },
+}

+ 26 - 0
src/api/mdm/kpi.js

@@ -0,0 +1,26 @@
+import Api from '../axios'
+
+const prefix = '/mdm/mdm/kpiManage'
+
+export default {
+  /* 获取数据库资源列表接口 */
+  listColumn (obj) {
+    return Api.get(prefix + '/listColumn', obj)
+  },
+  /* 通过ID数组批量字段信息 */
+  listColumnByIds (obj) {
+    return Api.get(prefix + '/listColumnByIds', obj)
+  },
+  /* 通过数据表Id获取数据表列表 */
+  listColumnByTableId (obj) {
+    return Api.get(prefix + '/listColumnByTableId', obj)
+  },
+  /* 获取已建数据库列表选项 */
+  listDatabase (obj) {
+    return Api.get(prefix + '/listDatabase', obj)
+  },
+  /* 通过数据库Id获取数据表列表 */
+  listTableByDatabaseId (obj) {
+    return Api.get(prefix + '/listTableByDatabaseId', obj)
+  }
+}

+ 66 - 0
src/api/mdm/storage.js

@@ -0,0 +1,66 @@
+import Api from '../axios'
+
+const prefix = '/mdm/mdm/storageManage'
+
+export default {
+  /* 建表-向导方式创建表 */
+  createTable (obj) {
+    return Api.post(prefix + '/createTable', obj)
+  },
+  /* 建表-扫描批量复制表 */
+  createTableByCopy (obj) {
+    return Api.post(prefix + '/createTableByCopy', obj)
+  },
+  /* 建表-DDL方式创建表 */
+  createTableByDDL (obj) {
+    return Api.post(prefix + '/createTableByDDL', obj)
+  },
+  /* 下载模板 */
+  downloadTemplateColums (obj) {
+    return Api.get(prefix + '/downloadTemplateColums', obj)
+  },
+  /* 根据表ID获取表信息接口 */
+  getTableInfoById (obj) {
+    return Api.getById(prefix + '/getTableInfoById', obj)
+  },
+  /* 根据数据库类型获取字段类型 */
+  listColumTypeByDatabaseType (obj) {
+    return Api.getById(prefix + '/listColumTypeByDatabaseType', obj)
+  },
+  /* 根据表ID获取表信息接口 */
+  listColumsByTableId (obj) {
+    return Api.getById(prefix + '/listColumsByTableId', obj)
+  },
+  /* 获取建表方式选项 */
+  listCreateTableOption (obj) {
+    return Api.get(prefix + '/listCreateTableOption', obj)
+  },
+  /* 获取已建数据库列表选项 */
+  listDatabaseOption (obj) {
+    return Api.get(prefix + '/listDatabaseOption', obj)
+  },
+  listDatabaseOptionAll (obj) {
+    return Api.get(prefix + '/listDatabaseOptionAll', obj)
+  },
+
+  /* 获取数据表信息 */
+  listTable (obj) {
+    return Api.get(prefix + '/listTable', obj)
+  },
+  /* 获取数据表信息-扫描数据源,包括原始库和目标库 */
+  listTableScan (obj){
+    return Api.get(prefix+'/listTableScan', obj)
+  },
+  /* 字段模板上传 */
+  loadTemplateColums (obj) {
+    return Api.post(prefix + '/loadTemplateColums', obj)
+  },
+  /* 删表接口 */
+  removeTableById (obj) {
+    return Api.deleteById(prefix + '/removeTableById', obj)
+  },
+  /* 修改表接口 */
+  updateTable (obj) {
+    return Api.put(prefix + '/updateTable', obj)
+  },
+}

+ 59 - 0
src/api/rpm/chart.js

@@ -0,0 +1,59 @@
+import Api from '../axios'
+
+const prefix = '/rpm/chart'
+
+export default {
+  /* 查询 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+  /* 添加 */
+  save (obj) {
+    return Api.post(prefix , obj)
+  },
+  /* 该状态 */
+  status (obj) {
+    return Api.putById(prefix + '/status', obj)
+  },
+  /* 该状态 */
+  delete (obj) {
+    return Api.deleteById(prefix , obj)
+  },
+  /* 该状态 */
+  get (obj) {
+    return Api.getById(prefix , obj)
+  },
+  /* 该状态 */
+  update (obj) {
+    return Api.putById(prefix , obj)
+  },
+  /* 通过分类ID获取接口列表信息 */
+  listInterfaceByProject (obj) {
+    return Api.getById(prefix + '/listInterfaceByProject', obj)
+  },
+  /* 通过接口ID获取接口出参节点 */
+  listInterfaceOutParams (obj) {
+    return Api.getById(prefix + '/listInterfaceOutParams', obj)
+  },
+  /* 获取接口分类信息 */
+  listInterfaceProject (obj) {
+    return Api.get(prefix + '/listInterfaceProject', obj)
+  },
+  /* 根据主题查询KPI列表 */
+  listKpiConfigs (obj) {
+    return Api.getById(prefix + '/listKpiConfigs', obj)
+  },
+  /* 通过接口ID获取接口出参节点 */
+  listProjectAndInterfaceTree (obj) {
+    return Api.get(prefix + '/listProjectAndInterfaceTree', obj)
+  },
+  /* 查询主题树(Ztree格式带检索) */
+  topicForZtree (obj) {
+    return Api.get(prefix + '/topicForZtree', obj)
+  },
+
+  /* 获取报表数据 */
+  getChartData (obj) {
+    return Api.post(prefix + '/getChartData', obj)
+  },
+}

+ 26 - 0
src/api/rpm/chartMenu.js

@@ -0,0 +1,26 @@
+import Api from '../axios'
+
+const prefix = '/rpm/rpm'
+
+export default {
+  /* 查询 */
+  getMenu (obj) {
+    return Api.getById(prefix + '/chartClass', obj)
+  },
+  /* 删除 */
+  deleteMenu (obj) {
+    return Api.deleteById(prefix + '/chartClass', obj)
+  },
+  /* 添加 */
+  addMenu (obj) {
+    return Api.post(prefix + '/chartClass', obj)
+  },
+  /* 获取树 */
+  getTree (obj) {
+    return Api.get(prefix + '/chartClass/tree', obj)
+  },
+  /* 通过数据库Id获取数据表列表 */
+  updateMenu (obj) {
+    return Api.putById(prefix + '/chartClass', obj)
+  },
+}

+ 30 - 0
src/api/rpm/menu.js

@@ -0,0 +1,30 @@
+import Api from '../axios'
+
+const prefix = '/rpm/rpm'
+
+export default {
+  /* 查询 */
+  getMenu (obj) {
+    return Api.getById(prefix + '/menu', obj)
+  },
+  /* 删除 */
+  deleteMenu (obj) {
+    return Api.deleteById(prefix + '/menu', obj)
+  },
+  /* 添加 */
+  addMenu (obj) {
+    return Api.post(prefix + '/menu', obj)
+  },
+  /* 获取树 */
+  getTree (obj) {
+    return Api.get(prefix + '/menu/tree', obj)
+  },
+  /* 通过数据库Id获取数据表列表 */
+  updateMenu (obj) {
+    return Api.putById(prefix + '/menu', obj)
+  },
+  /* 获取叶子结点未挂载报表的 */
+  leafTree (obj) {
+    return Api.get(prefix + '/menu/leafTree', obj)
+  }
+}

+ 115 - 0
src/api/rpm/report.js

@@ -0,0 +1,115 @@
+import Api from '../axios'
+
+const prefix = '/rpm/report'
+
+export default {
+  /* 查询 */
+  listType (obj) {
+    return Api.getById(prefix + '/listType', obj)
+  },
+  /* 根据主题查询KPI列表 */
+  listKpiConfigs (obj) {
+    return Api.getById(prefix + '/listKpiConfigs', obj)
+  },
+  /* 查询主题树(Ztree格式带检索) */
+  topicForZtree (obj) {
+    return Api.get(prefix + '/topicForZtree', obj)
+  },
+
+  /* 报表分页列表展示 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+
+  /* 新建报表--第一步 */
+  saveOne (obj) {
+    return Api.post(prefix + '/saveOne', obj)
+  },
+  /* 新建报表--第二步 */
+  saveTwo (obj) {
+    return Api.post(prefix + '/saveTwo', obj)
+  },
+  /* 新建报表--第三步 */
+  saveThree (obj) {
+    return Api.post(prefix + '/saveThree', obj)
+  },
+  /* 新建报表--第四步 */
+  saveFour (obj) {
+    return Api.post(prefix + '/saveFour', obj)
+  },
+  /* 新建报表--第五步 */
+  saveFive (obj) {
+    return Api.post(prefix + '/saveFive', obj)
+  },
+  /* 新建报表--第六步 */
+  saveSix (obj) {
+    return Api.post(prefix + '/saveSix', obj)
+  },
+
+  /* 修改报表状态 */
+  status (obj) {
+    return Api.putById(prefix + '/status', obj)
+  },
+  /* 报表删除 */
+  deleteById (obj) {
+    return Api.deleteById(prefix + '', obj)
+  },
+  /* 报表获取 */
+  getById (obj) {
+    return Api.getById(prefix + '', obj)
+  },
+  /* 子报表获取 */
+  listSonReport (obj) {
+    return Api.get(prefix + '/listSonReport', obj)
+  },
+  /* 父报表获取 */
+  listPReport (obj) {
+    return Api.get(prefix + '/listPReport', obj)
+  },
+  /* 用户获取 */
+  listUser (obj) {
+    return Api.get(prefix + '/listUser', obj)
+  },
+  /* 单个报表授权 */
+  reportRelUsers (obj) {
+    return Api.post(prefix + '/reportRelUsers', obj)
+  },
+  /* 多个报表授权 */
+  reportsRelUsers (obj) {
+    return Api.post(prefix + '/reportsRelUsers', obj)
+  },
+  /* 获取单个报表的用户 */
+  listRelUser (obj) {
+    return Api.getById(prefix + '/listRelUser', obj)
+  },
+  /* 删除 */
+  delete (obj) {
+    return Api.deleteById(prefix + '', obj)
+  },
+
+  /* 报表页面渲染 */
+  view (obj) {
+    return Api.getById(prefix + '/view', obj)
+  },
+  /* 报表页面数据查询 */
+  getReportData(obj){
+    return Api.post(prefix + '/getReportData', obj)
+  },
+  /* 查找分类下的报表 */
+  listReportByMenu(obj){
+    return Api.get(prefix + '/listReportByMenu', obj)
+  },
+
+  /* 查找分类下用户已授权的报表 */
+  listReportByUserAndMenu(obj){
+    return Api.get(prefix + '/listReportByUserAndMenu', obj)
+  },
+  /*  查找报表下全量kpi */
+  listKpiByReportId(obj){
+    return Api.getById(prefix + '/listKpiByReportId', obj)
+  },
+  /* 下载 */
+  downloadReportFile(obj){
+    return Api.post(prefix + '/downloadReportFile', obj)
+  },
+}

+ 55 - 0
src/api/task/task.js

@@ -0,0 +1,55 @@
+import Api from '../axios'
+
+const prefix = '/da/task'
+
+export default {
+  /* 新增采集任务 */
+  add (obj) {
+    return Api.post(prefix + '/add', obj)
+  },
+  /* 获取当前任务列表 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+  /* 获取当前数据库连接信息 */
+  database (obj) {
+    return Api.getById(prefix + '/list/database', obj)
+  },
+  /* 数据中心-->数据采集-->获取当前库当前表的所有字段信息 */
+  listColumnByTableId (obj) {
+    return Api.get(prefix + '/list/listColumnByTableId', obj)
+  },
+  /* 数据中心-->数据采集-->获取目标库数据库列表 */
+  listDatabase (obj) {
+    return Api.get(prefix + '/list/listDatabase', obj)
+  },
+  /* 数据中心-->数据采集-->获取源库数据库列表 */
+  listOriginal (obj) {
+    return Api.get(prefix + '/list/listOriginal', obj)
+  },
+  /* 数据中心-->数据采集-->获取当前数据库中所有表 */
+  listTableByDatabaseId (obj) {
+    return Api.get(prefix + '/list/listTableByDatabaseId', obj)
+  },
+  /* 数据中心-->数据采集-->启停任务,立即执行任务 */
+  operate (obj) {
+    return Api.putById(prefix + '/operate', obj)
+  },
+  /* 数据中心-->数据采集-->获取指定任务信息(回显) */
+  toEdit (obj) {
+    return Api.getById(prefix + '/toEdit', obj)
+  },
+
+  /* 获取数据表信息 */
+  listTable (obj) {
+    return Api.get(prefix + '/listTable', obj)
+  },
+  /* 更新任务 */
+  update (obj) {
+    return Api.putById(prefix + '/update', obj)
+  },
+  /* 删除任务 */
+  toDel (obj) {
+    return Api.deleteById(prefix+'/toDel',obj)
+  }
+}

+ 34 - 0
src/api/topic/topicList.js

@@ -0,0 +1,34 @@
+import Api from '../axios'
+
+const prefix = '/appshow/appshow/subjectManage'
+export default {
+
+  /* 保存专题信息 */
+  addSubjectInfo (obj) {
+    return Api.post(prefix, obj)
+  },
+  /* 专题左侧列表展示 */
+  list (obj) {
+    return Api.get(prefix + '/list', obj)
+  },
+  /* 主题配置接口,关联图表 */
+  relSubjectChart (obj) {
+    return Api.get(prefix + '/relSubjectChart', obj)
+  },
+  /* 修改专题状态接口 */
+  updateTopicState (obj) {
+    return Api.putById(prefix + "/state/", obj)
+  },
+  /* 专题配置接口 */
+  updateTopicById (obj) {
+    return Api.putById(prefix + '/', obj)
+  },
+  /* 根据ID获取专题信息 */
+  getTopicById (obj) {
+    return Api.getById(prefix + "/", obj)
+  },
+  /* 删除接口 */
+  delTopicInfo (obj) {
+    return Api.deleteById(prefix + "/" , obj)
+  }
+}

BIN
src/assets/3D-logo.png


BIN
src/assets/arrows-small.png


BIN
src/assets/arrows.png


BIN
src/assets/ava.jpg


BIN
src/assets/login-bg.1.jpg


BIN
src/assets/login-bg.jpg


BIN
src/assets/login-sec-bg.png


BIN
src/assets/login-thr-bg.png


BIN
src/assets/logo-icon.png


BIN
src/assets/logo.png


BIN
src/assets/logo_blue.png


BIN
src/assets/myfont/FZDHTJW.ttf


File diff suppressed because it is too large
+ 161 - 0
src/assets/myfont/iconfont.css


File diff suppressed because it is too large
+ 101 - 0
src/assets/myfont/iconfont.css.bak


BIN
src/assets/myfont/iconfont.eot


File diff suppressed because it is too large
+ 1 - 0
src/assets/myfont/iconfont.js


File diff suppressed because it is too large
+ 134 - 0
src/assets/myfont/iconfont.svg


BIN
src/assets/myfont/iconfont.ttf


BIN
src/assets/myfont/iconfont.woff


BIN
src/assets/myfont/iconfont.woff2


BIN
src/assets/pie.png


BIN
src/assets/report/biaoge1.png


BIN
src/assets/report/biaoge2.png


BIN
src/assets/report/biaoge3.png


BIN
src/assets/report/biaoge4.png


BIN
src/assets/zhexian.png


BIN
src/assets/zhu1.png


BIN
src/assets/zhu2.png


BIN
src/assets/zhu3.png


BIN
src/assets/zhu4.png


+ 16 - 0
src/class/Report/BaseClass.js

@@ -0,0 +1,16 @@
+import {recognizeType} from './recognizeType'
+/*
+*  默认搜索条件
+* */
+export class BaseClass {
+  constructor(extra={}) {
+
+  }
+
+  update(params){
+    if(recognizeType.IsObject(params)){
+      Object.assign(this, params)
+    }
+  }
+
+};

+ 31 - 0
src/class/Report/KpiDrillParam.js

@@ -0,0 +1,31 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  默认搜索条件
+* */
+export class SearchForm extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 分页
+    this.pageSize = 10
+    // 当前页
+    this.page = 1
+    // 排序字段
+    this.sort = 'createTime'
+    // 排序方式
+    this.order = 'desc'
+
+    this.update(extra)
+
+  }
+
+  setPage(res){
+    if(res.code == 1){
+      if(res.hasOwnProperty('page')){
+        this.page = res.page
+      }
+      if(res.hasOwnProperty('pageSize')){
+        this.pageSize = res.pageSize
+      }
+    }
+  }
+};

+ 12 - 0
src/class/Report/recognizeType.js

@@ -0,0 +1,12 @@
+export const recognizeType = (function() {
+  let type = {};
+  let typeArr = ['String', 'Object', 'Number', 'Array','Undefined', 'Function', 'Null', 'Symbol'];
+  for (let i = 0; i < typeArr.length; i++) {
+    (function(name) {
+      type['Is' + name] = function(obj) {
+        return Object.prototype.toString.call(obj) == '[object ' + name + ']';
+      }
+    })(typeArr[i]);
+  }
+  return type;
+})();

+ 16 - 0
src/class/SearchTable/BaseClass.js

@@ -0,0 +1,16 @@
+import {recognizeType} from './recognizeType'
+/*
+*  默认搜索条件
+* */
+export class BaseClass {
+  constructor(extra={}) {
+
+  }
+
+  update(params){
+    if(recognizeType.IsObject(params)){
+      Object.assign(this, params)
+    }
+  }
+
+};

+ 31 - 0
src/class/SearchTable/SearchForm.js

@@ -0,0 +1,31 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  默认搜索条件
+* */
+export class SearchForm extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 分页
+    this.pageSize = 10
+    // 当前页
+    this.page = 1
+    // 排序字段
+    this.sort = 'createTime'
+    // 排序方式
+    this.order = 'desc'
+
+    this.update(extra)
+
+  }
+
+  setPage(res){
+    if(res.code == 1){
+      if(res.hasOwnProperty('page')){
+        this.page = res.page
+      }
+      if(res.hasOwnProperty('pageSize')){
+        this.pageSize = res.pageSize
+      }
+    }
+  }
+};

+ 26 - 0
src/class/SearchTable/TableData.js

@@ -0,0 +1,26 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table数据
+* */
+export class TableData extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 数据
+    this.data = []
+    // 总数
+    this.total = 0
+    this.page = 1
+
+    this.update(extra)
+
+  }
+
+  setData(res){
+    if(res.code == 1){
+      this.data = res.data||[]
+      this.page = res.page
+      this.total=res.totalNumber
+    }
+  }
+
+};

+ 32 - 0
src/class/SearchTable/TableLabel.js

@@ -0,0 +1,32 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table列
+* */
+export class TableLabel extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 字段名
+    this.prop = ''
+    // 字段中文名
+    this.title = ''
+    // 列宽
+    this.width = ''
+    // 额外附件的class名
+    this.className = ''
+    // 是否可排序
+    this.sort = false
+    // 列类型:img、imgs
+    this.type = null
+    // 是否固定咧
+    this.fixed = false
+    // 超出是否隐藏
+    this.ellipsis = true
+    // 如果是图片类型,则设置图片宽高
+    this.imgWidth = 100
+    // 设置内容颜色,参考TableLabelColorOption
+    this.colorOption = null
+
+    this.update(extra)
+
+  }
+};

+ 16 - 0
src/class/SearchTable/TableLabelColorOption.js

@@ -0,0 +1,16 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table内容颜色设置
+* */
+export class TableLabelColorOption extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // option = {'1':'safe'}
+    this.option = {}
+    // depend 字段名 如 'status'
+    this.depend = ''
+
+    this.update(extra)
+
+  }
+};

+ 18 - 0
src/class/SearchTable/TableLabelTrigger.js

@@ -0,0 +1,18 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table内容设置为开关
+* */
+export class TableLabelTrigger extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 开关激活值
+    this.activeValue = 1
+    // 开关关闭值
+    this.inActiveValue = 0
+    // 开关调用方法
+    this.methods = ''
+
+    this.update(extra)
+
+  }
+};

+ 14 - 0
src/class/SearchTable/TableOperate.js

@@ -0,0 +1,14 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table操作
+* */
+export class TableOperate extends BaseClass {
+  constructor(extra={}) {
+    super()
+    this.width = 0
+    this.buttons = []
+
+    this.update(extra)
+
+  }
+};

+ 15 - 0
src/class/SearchTable/TableOperateButton.js

@@ -0,0 +1,15 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table操作按钮
+* */
+export class TableOperateButton extends BaseClass {
+  constructor(extra={}) {
+    super()
+    this.label = ''
+    this.methods = ''
+    this.color = ''
+
+    this.update(extra)
+
+  }
+};

+ 29 - 0
src/class/SearchTable/TableOption.js

@@ -0,0 +1,29 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table设置
+* */
+export class TableOption extends BaseClass {
+  constructor(extra={}) {
+    super()
+    // 是否显示序号
+    this.index = true
+    // 是否显示勾选框
+    this.select = false
+    // 默认排序
+    this.defaultSort = {prop: 'createTime', order: 'desc'}
+    // 配置是否显示网格
+    this.border = false
+    // 分页样式
+    this.pageStyle = {
+      layout: 'default',
+      background: false
+    }
+    // 列信息
+    this.tableLabel = []
+    // 行尾操作
+    this.tableOperate = false
+
+    this.update(extra)
+
+  }
+};

+ 15 - 0
src/class/SearchTable/TablePageParam.js

@@ -0,0 +1,15 @@
+import {BaseClass} from "./BaseClass";
+/*
+*  table操作
+* */
+export class TablePageParam extends BaseClass {
+  constructor(extra={}) {
+    super()
+    this.pageSize = 10
+    this.page = 1
+    this.pageSizes = [10,15,20,50]
+
+    this.update(extra)
+
+  }
+};

+ 33 - 0
src/class/SearchTable/index.js

@@ -0,0 +1,33 @@
+import {SearchForm} from './SearchForm'
+import {TableData} from "./TableData";
+import {TableLabel} from "./TableLabel";
+import {TableLabelColorOption} from "./TableLabelColorOption";
+import {TableLabelTrigger} from "./TableLabelTrigger";
+import {TableOperate} from "./TableOperate";
+import {TableOperateButton} from "./TableOperateButton";
+import {TableOption} from "./TableOption";
+import {TablePageParam} from "./TablePageParam";
+
+export {
+  SearchForm,
+  TableData,
+  TableLabel,
+  TableLabelColorOption,
+  TableLabelTrigger,
+  TableOperate,
+  TableOperateButton,
+  TableOption,
+  TablePageParam
+}
+
+export default {
+  SearchForm,
+  TableData,
+  TableLabel,
+  TableLabelColorOption,
+  TableLabelTrigger,
+  TableOperate,
+  TableOperateButton,
+  TableOption,
+  TablePageParam
+}

+ 12 - 0
src/class/SearchTable/recognizeType.js

@@ -0,0 +1,12 @@
+export const recognizeType = (function() {
+  let type = {};
+  let typeArr = ['String', 'Object', 'Number', 'Array','Undefined', 'Function', 'Null', 'Symbol'];
+  for (let i = 0; i < typeArr.length; i++) {
+    (function(name) {
+      type['Is' + name] = function(obj) {
+        return Object.prototype.toString.call(obj) == '[object ' + name + ']';
+      }
+    })(typeArr[i]);
+  }
+  return type;
+})();

+ 346 - 0
src/components/automatic-graph-components/chart.vue

@@ -0,0 +1,346 @@
+<template>
+  <div class="report-container report-preview" >
+    <div class="report-data-container" :class="reportLayer">
+    <div class="report-chart-container " :class="chartLayer">
+      <!--echarts-->
+      <div class="line-chart" :id="'lineChart_'+groupIndex" v-if="ifBar"></div>
+      <div class="pie-chart" :id="'pieChart_'+groupIndex" v-if="ifPie"></div>
+      <div class="map-chart" :id="'mapChart_'+groupIndex" v-if="ifMap"></div>
+    </div>
+    </div>
+    <!--下钻弹窗-->
+  </div>
+</template>
+
+<script>
+  import {kpiColors} from '@/views/Report/ReportManagement/kpi-color'
+  import {barLineOption,pieOption,mapOption} from '@/views/Graph/GraphManagement/echarts-option'
+  import {echartsThemes} from '@/views/Report/ReportManagement/echarts-color-themes'
+  import {deepCopy, randomStr, numberFormateThousand, GetDateStr} from '@/utils/util'
+
+  export default {
+    name: "report",
+    props: {
+      // table和charts的布局关系
+      reportLayer: {
+        default: 'report-layer-column'
+      },
+      // chart接chart的布局关系
+      chartLayer: {
+        default: 'chart-layer-column'
+      },
+      chartId: {
+        default: false
+      },
+      // 给echart用的唯一id
+      groupIndex: {
+        // 这个随机数在一次执行队列里输出的都一样,所以不适用于分组展示的情况
+        default: randomStr(),
+      },
+    },
+    data() {
+      return {
+        // 图表默认配置
+        barLineOption: barLineOption,
+        pieOption: pieOption,
+        mapOption: mapOption,
+        viewRes: null
+      }
+    },
+    computed: {
+      chartType: {
+        // getter
+        get: function () {
+          return (this.viewRes && this.viewRes.chartType)||null
+        },
+        // setter
+        set: function (newValue) {
+        }
+      },
+      ifMap: {
+        // getter
+        get: function () {
+          let {chartType} = this
+          return chartType === 3
+        },
+        // setter
+        set: function (newValue) {
+        }
+      },
+      ifBar: {
+        // getter
+        get: function () {
+          let {chartType} = this
+          return chartType === 1
+        },
+        // setter
+        set: function (newValue) {
+        }
+      },
+      ifPie: {
+        // getter
+        get: function () {
+          let {chartType} = this
+          return chartType === 2
+        },
+        // setter
+        set: function (newValue) {
+        }
+      },
+      /* 表颜色 */
+      chartTheme: {
+        get: function () {
+          let obj = null
+          if(this.viewRes){
+            let {colorGroupId} = this.viewRes
+            obj = echartsThemes[colorGroupId]
+          }
+          return obj
+        },
+        set: function (val) {}
+      },
+      chartColor: {
+        // getter
+        get: function () {
+          let arr = []
+          let {chartTheme} = this
+          if(chartTheme){
+            arr = chartTheme.data
+          }
+          return arr
+        },
+        // setter
+        set: function (newValue) {
+        }
+      },
+    },
+    watch:{
+    },
+    created(){
+    },
+    mounted(){
+      this.getList()
+    },
+    methods: {
+      loadMap(){
+        let {chartId} = this
+        /* 合成检索条件 */
+        let params = {chartId}
+        this.$api.chart.getChartData(params)
+          .then(res => {
+            if (res.code == 1) {
+              this.getMapChart(res.data.map)
+            }
+          })
+      },
+      loadPie(){
+        let {chartId} = this
+        /* 合成检索条件 */
+        let params = {chartId}
+        this.$api.chart.getChartData(params)
+          .then(res => {
+            if (res.code == 1) {
+              this.getPieChart(res.data.pie)
+            }
+          })
+      },
+      loadBarAndLine(){
+        let {chartId} = this
+        /* 合成检索条件 */
+        let params = {chartId}
+        this.$api.chart.getChartData(params)
+          .then(res => {
+            if (res.code == 1) {
+            this.getBarLineChart(res.data.barOrLine)
+
+            }
+          })
+      },
+      getList(){
+        let params = { id: this.chartId }
+        this.$api.chart.get(params)
+          .then(res => {
+            if (res.code == 1) {
+              this.viewRes = res.data
+              if(this.ifBar){
+                this.loadBarAndLine()
+              }
+              if(this.ifPie){
+                this.loadPie()
+              }
+              if(this.ifMap){
+                this.loadMap()
+              }
+            }
+          })
+      },
+
+      getBarLineChart(data){
+        let xAxisColor={
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: '#7f8d9a'
+            }
+          },
+          nameTextStyle:{
+            color: '#7f8d9a',
+          },
+          axisLine:{
+            lineStyle:{
+              color: '#7f8d9a',
+              width: 1
+            }
+          },
+        }
+        let yAxisColor={
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: '#7f8d9a'
+            },
+            formatter: '{value}'
+          },
+          axisLine:{
+            lineStyle:{
+              color: '#7f8d9a',
+              width: 1
+            },
+          },
+          splitLine:{
+            show:true,
+            lineStyle:{
+              color: '#7f8d9a',
+              width: 1
+            }
+          },
+        }
+        let xAxis=data.xAxis
+        let yAxis=data.yAxis
+        let series=data.series
+
+        series.forEach(item=>{
+          if(item.unit){
+            item.name=item.name+'('+item.unit+')'
+          }
+        })
+
+        yAxis.forEach((item)=>{
+          Object.assign(item,yAxisColor)
+        })
+
+
+        Object.assign(xAxis,xAxisColor)
+
+        let barWidth=20
+
+        let barSeries=series.filter(item=>{
+          return item.type==="bar"
+        })
+
+        let barNum=barSeries.length
+
+        if(barNum>40){
+          barWidth=800/barNum
+        }
+
+        if(barWidth<5){
+          barWidth=5
+        }
+
+        series.map((item)=>{
+          return Object.assign(item,{barWidth})
+        })
+
+        let option=this.barLineOption
+        option.color=this.chartColor
+        option.xAxis=[xAxis]
+        option.yAxis=yAxis
+        option.series=series
+
+
+        // console.log(JSON.stringify(option))
+
+        let myChart = this.$echarts.init(document.getElementById('lineChart_'+this.groupIndex))
+
+        // 绘制图表
+        myChart.setOption(option,true)
+
+        this.$nextTick(function () {
+          myChart.resize()
+        })
+      },
+      getPieChart(data){
+        let option=this.pieOption
+        option.color=this.chartColor
+        option.series.data=data.series.map(item=>{
+          item.value = Number(item.value)
+          return item
+        })
+
+        // console.log(JSON.stringify(option))
+
+        let myChart = this.$echarts.init(document.getElementById('pieChart_'+this.groupIndex))
+
+        // 绘制图表
+        myChart.setOption(option,true)
+
+        this.$nextTick(function () {
+          myChart.resize()
+        })
+      },
+      getMapChart(data){
+        let option=this.mapOption
+
+        let map = new BMap.Map('mapChart_'+this.groupIndex)         // 创建地图实例
+        // let pot = this.searchForm.cityAddr.split(",") || []
+        // let lng = pot[0], lat = pot[1]
+        // let point = new BMap.Point(lng, lat)
+        let point = new BMap.Point(116.3964,39.9093)
+        map.centerAndZoom(point, 13)   // 初始化地图,设置中心点坐标和地图级别
+        map.enableScrollWheelZoom()// 允许滚轮缩放
+        map.setMapStyle({
+          styleJson: option
+        }) // 午夜蓝风格(midnight)
+        map.setCenter('犍为县')
+        // map.setCenter(this.searchForm.cityCode)
+        this.mapObj = map
+        this.realtimeHeatmap(data)
+        let pt = new BMap.Point(116.3964,39.9093)
+        let myIcon = new BMap.Icon(icon, new BMap.Size(53,50))
+        let marker2 = new BMap.Marker(pt,{icon:myIcon})  // 创建标注
+        this.mapObj.addOverlay(marker2)
+        marker2.addEventListener("onmouseover",(e) => {
+          var opts = {
+            width : 130,     // 信息窗口宽度
+            height: 100,     // 信息窗口高度
+            title : "" , // 信息窗口标题
+            enableMessage:true,//设置允许信息窗发送短息
+            message:"",
+          }
+          let text = '<div class="el-bs-window"></div>'
+          let infoWindow = new BMap.InfoWindow(text, opts);  // 创建信息窗口对象
+          this.mapObj.openInfoWindow(infoWindow,e.point); //开启信息窗口
+        })
+      },
+      // 热力图
+      realtimeHeatmap (data) {
+        let params = {areaCode: "511123"}
+        let heatmapOverlay = new BMapLib.HeatmapOverlay({"radius":20})
+        this.mapObj.addOverlay(heatmapOverlay)
+        let points =data
+        heatmapOverlay.setDataSet({data:points,max:4500})
+        heatmapOverlay.setOptions({ "gradient" : {
+            0:'#25cef3',
+            .2:'#d01864',
+            .4:'#1979f2',
+            .6:'#1979f2',
+            .8:'#f3c525',
+            1:'#e60012',
+          }})
+        heatmapOverlay.show()
+
+      },
+    },
+  }
+</script>

+ 68 - 0
src/components/automatic-report-components/date-month.vue

@@ -0,0 +1,68 @@
+<template>
+  <div class="data-range-container">
+    <el-button type="primary" @click="previous">前一月</el-button>
+    <el-date-picker
+      v-model="datePrivate"
+      type="month"
+      format="yyyy 第 MM 月"
+      :picker-options="dateOption"
+      placeholder="选择月">
+    </el-date-picker>
+    <el-button type="primary" @click="next">后一月</el-button>
+  </div>
+</template>
+
+<script>
+  import {GetDateStr, getLastMonthDay, GetNextMonthDay, GetPreMonthDay} from '@/utils/util'
+  export default {
+    name: 'date-signal',
+    props: {
+      value:{ // 必须要使用value
+        default: ()=>([]),
+      },
+    },
+    data() {
+      return {
+        datePrivate: '',
+        dateOption:{
+          firstDayOfWeek: 1,
+          disabledDate: (time) => {
+            return time.getTime() > this.today;
+          }
+        },
+      }
+    },
+    computed: {
+      today: {
+        get: function(){
+          return (new Date()).getTime()
+        },
+      },
+    },
+    watch:{
+      datePrivate(val) {
+        let arr=['', '']
+        if (val) {
+          arr = [GetDateStr(val,0), getLastMonthDay(val)]
+        }
+        this.$emit('input', arr)
+      },
+    },
+    mounted(){
+      // console.log(this.total)
+    },
+    methods: {
+      next(){
+        let current=this.datePrivate?this.datePrivate:new Date()
+        let newDate=GetNextMonthDay(current,1)
+        this.datePrivate=new Date(newDate.replace(/-/g, '/'))
+      },
+      previous(){
+        let current=this.datePrivate?this.datePrivate:new Date()
+        let newDate=GetPreMonthDay(current,1)
+        this.datePrivate=new Date(newDate.replace(/-/g, '/'))
+      }
+    },
+  }
+</script>
+

+ 0 - 0
src/components/automatic-report-components/date-range.vue


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